TL;DR
In bash we can get the last argument like this:
${@: -1}
And all the previous arguments like this:
${@:1:$#-1}
General
You need to call some arbitrary program from a script, but you don't know how many arguments will it have.
You know that this program does something on a file.
So our script will receive at least two arguments: a command (to call our program) and a file name.
(Yes, we can change the arguments order for file to be first, but I think this is not so ideomatic.)
Here is a simple bash-script for that:
#!/usr/bin/env bash
CMD="${@:1:$#-1}"
FILE="${@: -1}"
if [[ -z "$CMD" ]]
then
echo "No open command."
exit 1
fi
if [[ -z "$FILE" ]]
then
echo "No file to open."
exit 1
fi
$CMD "$FILE"
Call it like so: open.sh COMMAND FILE
.
Broot
Originally, I was looking for a way to open files from broot file manager. By design, broot pauses while the file is opened - so it is not particularly comfortable (I mean, possible) to open several files at once.
But we can instruct broot to open files with an arbitrary script, in which we can run target command in a background (see nohup
and disown
at the bottom).
Here is a slightly modified script for broot to call. Place it as ~/.config/broot/open_detached.sh
:
#!/usr/bin/env bash
# Open files and leave broot working.
# Source: https://github.com/Canop/broot/issues/38#issuecomment-583843143
CMD="${@:1:$#-1}"
FILE="${@: -1}"
if [[ -z "$CMD" ]]
then
echo "No open command."
exit 1
fi
if [[ -z "$FILE" ]]
then
echo "No file to open."
exit 1
fi
nohup $CMD "$FILE" > /dev/null & disown
Now we can use that script in broot config. Here is an example how I configured image opening with feh:
verbs: [
{
key: enter
extensions: [
"xcf" "xbm" "xpm" "ico" "svg"
"jpeg" "jpg" "bmp" "png" "tiff"
]
execution: "~/.config/broot/open_detached.sh feh --scale-down --auto-zoom {file}"
leave_broot: false
}
]
Shout-out to oj-lappi for inspiration!
Top comments (0)