2

The feh command allows you to view images within a folder recursively:

feh --recursive --auto-zoom

While viewing images, it also allows you to associate custom commands with keys 0-9 on your keyboard. For example, if I wanted the terminal to output the filename of the image I was viewing (to the terminal), I could make it do that by pressing the zero key while the image is being displayed by running feh with an --action argument like this:

feh --recursive --auto-zoom --action "echo '%f'"

--action binds the command echo '%f' to the zero key. %f is the relative path and looks like this when outputted ./filename.jpg.

However, I need feh to give me the absolute path instead of a relative path. So, I need to cut off that dot and then append what's left onto the pwd.

This is my attempt to do that:

feh --recursive --auto-zoom --cache-size 2048 --action "echo $(pwd)$(echo '%f' | cut -c 2-)}"

but the output looks like this:

/absolute/pathf

(notice the 'f' on the end of the pwd)

How can I instead achieve an output like this? :

/absolute/path/filename.jpg

2 Answers 2

3

Just do:

feh --recursive --auto-zoom --action 'printf "%%s\n" %F' "$PWD"

That is:

  • pass the full path of the current working directory to feh (instead of nothing which feh treats the same as .) so it will give you the full path of files within.
  • use %F, not %f so the quoting is done correctly (your '%f' would choke on filenames containing ' characters, that would even make it an arbitrary command execution vulnerability (imagine a file named ';reboot #.jpg or worse for instance)).
  • don't use echo which in general can't be used to display arbitrary data.
  • the literal % that we need to pass to printf must be escaped as %% (%s alone would be expanded by feh to the size of the file).
  • we use single quotes (the strongest quotes) for the action argument to pass to feh. The argument will be literally: printf "%%s\n" %F. That tells feh to invoke a shell (/bin/sh) to interpret that code with 3 arguments: sh, -c and that code with %% changed to % and %F changed to the path of the file properly quoted in sh syntax, and sh, in turn, will invoke printf (which is builtin in most sh implementations) with printf, %s\n and the full path of the file as arguments.
0
0

Hi Stéphane and thanks for this fantastic answer.

I have made use of your one-liner for the purpose of being able to tag files in my favourite terminal file-manager, ranger, whilst within feh. To do this, I used the following argument:

feh -FZd --action 'printf "%%s\n" %F' "$PWD" >> ~/.local/share/ranger/tagged image.jpg

Ranger stores tagged images very simply by adding the file path to the end of a text file. When you untag an image, it removes this filepath.

I have however run into an issue when integrating this into ranger's file opener/executor, rifle. Rifle is essentially a file executor that does some file-type checking to work out what you want to use to open a file. I added the above one-liner to rifle like so:

mime ^image, has feh,      X, flag f = feh -FZd --action 'printf "%%s\n" %F' "$PWD" >> ~/.local/share/ranger/tagged -- "$@"

Flag f forks the process, X tells it that a graphical environment is available. Then there's the mime type. None of this causes an issue. The part that breaks my argument is the $@ on the end.

This is also essential to tell ranger to open the currently focused file and not just start at the top of the directory. Unfortunately, with this environment variable added to the argument, instead of appending the entire file path to the end of the ~/.local/share/ranger/tagged file, it appends just the file name.

e.g.

This: /home/$USER/photos/IMG_20221023_102228_HDR~2.jpg

Becomes this: IMG_20221023_102228_HDR~2.jpg

I'm not sure why this is happening but I know it has to do with the $@ environment variable. If I remove $@ and replace it with $1 (referring to the n-th selected file instead), my argument works properly again only, as mentioned before, feh starts at the top of the directory rather than on the focused file.

I'm sorry I can't explain this any better. I hope it makes sense. Would love to get this working properly!

PS I know I shouldn't really be asking a question here... Although with a little help, this may well turn into an answer for someone as it's still closely related to the initial question.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .