前に 🐧 ファイルマネージャで無圧縮 ZIP を作成する なんてのを書いたけどそもそもデスクトップエントリだけでできないの?と思ったので色々検証しつつやってみた。
Terminal=1
や Terminal=true
で動作確認する場合は処理が完了するとすぐにターミナルが終了してしまうので ; sleep 10
や ; read f
で待機させたり、| logger
などでシステムログに記録して tail -F /var/log/syslog
で監視しておけばよい。
まず、Exec 行には ;
や |
、&&
、||
などを書いても良い。
Exec=echo %f; false || sleep 3
%f
と %F
の動作の違いは一度にいくつのファイルを処理するかという点。
%f
の場合はファイル数分 Exec 行が実行される。for
に似ているが前のコマンドの終了を待たずにほぼ同時に実行されるためファイル数が多い場合は注意が必要。
Exec=echo %f
以下の場合は全てのファイルパスが echo
に渡されるので1回しか実行されない。
Exec=echo %F
%f
や %F
を省略した場合は Exec 行の最後に %f
を挿入したときと同じ動作が行われる。以下の場合、最初の echo
は改行を出力するのみでファイルパスは次の echo
に渡され、この Exec がファイル数分行われる。
# Same as # Exec=echo; echo %f Exec=echo; echo
%f
はシェル上で言えばクオートされた状態で展開されるのでクォートで括る必要はない。Path=
キーによる指定が無い場合、%f
ならファイル毎に親ディレクトリがカレントディレクトリになり、%F
なら最初に選択したファイルの親ディレクリがカレントディレクトリになる。ただし、ファイルブラウザによって異なるかもしれないので pwd
で事前に確認した方がいいかもしれない。
以下は同じパスを示すはず。
Exec=pwd; cd "$(dirname %f)" && pwd; sleep 3
Exec の最初のコマンドでは代入式は使えない(env
コマンドがあれば使える)が、2つ目以降のコマンドでは代入式が使えるらしい。なので1つ目のコマンドに :
とか set -x
とか適当なものを置いておくだけでいいっぽい。
Exec=:; foo=%f; echo $foo; sleep 3
というわけでログを取りつつ無圧縮 ZIP を連続で作成するデスクトップエントリはこうなった。${f%%/*}
はデスクトップエントリの処理によって ${f%/*}
となるためシェルスクリプトに書いた時と意味が異なる。
Exec=set -ex -- %F; for f; do test -d "${f}" || continue; cd "${f%%/*}"; zip -0mrTX -x"*".desktop "${f}".zip "${f##*/}"; done 2>&1 | logger -t zip
セミコロンを使わずに書くならこう。
set -ex -- %F for f do test -d "${f}" || continue cd "${f%%/*}" zip -0mrTX -x"*".desktop "${f}".zip "${f##*/}" done 2>&1 | logger -t zip
改行は書けないっぽいか…。Ruby で書いたほうがクオート処理少なくて済むかな。