Open mcmikemn opened 5 months ago
Global option -r
would resolved any symlinks, so that is not the option you want to use. You can display stats of symlinks themselves, adding an l
in front. This only works with stat commands, meaning those starting with a dot like {.isdir
. Look at the help with fpath -H fmt
to see a list of them. All of the {.
commands exist as same as {.l
, which do not follow links and handle symlinks themselves.
So simply replace {.isdir:
with {.lisdir:
and {.islink:
with {.lislink:
. Do the same with {.isreg}
. Here is the modified variant of the last command you gave:
find -P ./.* -maxdepth 1 | fpath -a -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.lisreg:{name}}{red}{.lislink:{name} -> {path}}{/color}{blue}{.lisdir:{name}}{/color}'
Does this work as expected?
Edit: Don't forget {.mode}
to replace with {.lmode}
too, if that is what you want.
Thanks for your help. This is a really comprehensive utility!
But I'm still doing something wrong.
\ls -a1 | fpath -r -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.lisreg:{name}}{red}{.lislink:{name} -> {path}}{/color}{blue}{.lisdir:{name}}{/color}
results in showing the name of the target of a symlink, and not in a color or with the path as I specify:
-rwxr-xr-x mike / mike 2017-09-21 9.3 KB smb.conf
drwxrwxr-x mike / mike 2020-08-18 4.0 KB .simdock
-rw-rw-r-- mike / mike 2021-10-16 16.5 KB lutris.log
(smb.conf
and lutris.log
are displayed in white, and .simdock
is displayed in blue. And note that they display the name of the target of the symlink and are listed alphabetically where the name of the symlink would be.)
For reference, here is the result of \ls -al
:
-rw-rw-r-- 1 mike mike 16860 Oct 16 2021 lutris.log
drwxrwxr-x 2 mike mike 4096 Aug 18 2020 .simdock
-rwxr-xr-x 1 mike mike 9542 Sep 21 2017 smb.conf
lrwxrwxrwx 1 mike mike 10 Jun 3 06:47 testlink -> ./smb.conf
lrwxrwxrwx 1 mike mike 9 Jun 3 06:48 testlink2 -> .simdock/
lrwxrwxrwx 1 mike mike 10 Jun 4 07:10 testlink3 -> lutris.log
That's because you have still the global option fpath -r
in use, which will resolve all symlinks before it hits the -F
option. Remove the -r
option.
Doh! Of course you're right. Thanks again.
Unrelated: my command (after I removed -r
) has {.lislink:{name} -> {path}}
, and the result is:
symlink -> symlink
instead of
symlink -> /full/path/to/target
I assume this is because both {name}
and {path}
are directed to the symlink. But what I want is the name of the symlink but the path of the symlink's target. I didn't find anything about an alternative {path}
command. Is there an option for this?
Hmm, I didn't think too deep into this before. Have in mind the script operates on a fairly simple manner. So limitations are expected. Just a disclaimer. :-)
So your goal is to display the name of the symlink with the path it resolves to; just like what ls
does. The {.lislink:{name} -> {path}}
does exactly that, it displays the name of the link file and the full path to of this same link file. There is no evaluation of the symlink to its target at the moment. So right now we can't do that.
But I have looked into the Python documentation and found something that could be useful for this. Maybe I change all to evaluate the symbolic link by default like the {.
based stat commands, and provide an l
. But I have to test this before and see if it works.
That would be cool.
v0.12 Hi I finally found some time again and got things sorted out. Instead giving l
variants to each path and filename based commands, there are now r
based commands to resolve symlink. There was a debate which way I should have done this, but there are good reasons. Take your previous command here and try it out. Here it is:
\ls -A1 | fpath -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.lisreg:{name}}{red}{.lislink:{name} -> {rpath}}{/color}{blue}{.lisdir:{name}}{/color}'
Notice I use \ls -A1
instead -a1
, because of the "." and ".." directories. Also this is still not perfect, because a symbolic link that points to a non existent file is displayed as an (almost) empty line.
Changelog: https://github.com/thingsiplay/fpath/blob/main/CHANGES.md
Thanks for adding this feature!
However, I get this error:
$ ls
Traceback (most recent call last):
File "/usr/local/bin/fpath", line 1388, in <module>
exit(main())
File "/usr/local/bin/fpath", line 1379, in main
for path in app:
File "/usr/local/bin/fpath", line 430, in __iter__
for index, path in enumerate(self.apply_format(), start=1):
File "/usr/local/bin/fpath", line 690, in apply_format
if "{.l" in fmt and entry.exists:
File "/usr/local/bin/fpath", line 85, in exists
self.exists_cache = self.work_path.exists(follow_symlinks=False)
TypeError: Path.exists() got an unexpected keyword argument 'follow_symlinks'
Edit: Spelled "Python" a few times less. It was repetitive.
Oh no, this is not good. Because I see this "follow_symlinks" feature in Python got added to its standard library in in version 3.12. You have a version that is older than this, which makes sense as the most distributions don't have the newest one. This is one of the shortcomings of Python and definitely unfortunate then.
I could provide a compiled binary in the releases page (its truly compiled to C code with Nuitka). This makes it independent from any Python version or library you have installed, but loses its open nature of the script. Otherwise you have to use the older version, because there is not much else I can do about (I think).
Ah. Well I definitely recommend remaining open and not offering a compiled executable. :)
I can try to install a newer python, but from past experience, that's not necessarily easy. Thanks for adding the feature. I'll catch up someday.
I would highly discourage from updating your system Python, as this can cause lot of issues and incompatibilities. There are AppImages of Python like https://github.com/niess/python-appimage/releases/tag/python3.12 (which are binaries obviously).
I'm sorry for this complicated mess. I will look into the code again to see if can come up with any solution to this.
I used pyenv
and it was super easy: pyenv install 3.12.0
and then pyenv global 3.12.0
.
fpath
now works. I have yet to find out if anything else I have that requires python is going tohave problems. :)
And the new {rpath}
works great. :)
That's nice. If you have multiple Python versions installed, then I would recommend to leave the original one at default. Then just adapt the line from the script to call the correct Python version, something like #!/usr/bin/env Python3.12
or like that. Then you can opt in to the specific version of Python for any script you like, while the system version is unaffected.
Just a suggestion. Good to see it works. However most people don't have the newest version available, so I need to find a solution (if there is one).
I'm trying to display symbolic links in red. The following command displays them in blue if they point to a directory, or white (default color) if they point to a file.
\ls -a1 | fpath -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.isreg:{name}}{red}{.islink:{name} -> {path}}{/color}{blue}{.isdir:{name}}{/color}'
I've also tried with
-r
:\ls -a1 | fpath -r -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.isreg:{name}}{red}{.islink:{name} -> {path}}{/color}{blue}{.isdir:{name}}{/color}'
I've also tried with
find -P
instead ofls
:find -P ./.* -maxdepth 1 | fpath -r -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.isreg:{name}}{red}{.islink:{name} -> {path}}{/color}{blue}{.isdir:{name}}{/color}'
..and with
find -P
but without-r
:find -P ./.* -maxdepth 1 | fpath -a -s blue -F'{red}{.mode}{/color}\t{owner} {green}/{/color} {group}\t{.mtime:%Y-%m-%d}\t{.size} \t{.isreg:{name}}{red}{.islink:{name} -> {path}}{/color}{blue}{.isdir:{name}}{/color}'
Examples:
(in the
fpath
example, "testlink" is white and "testlink2" is blue)