
PATH
私はposixシェルがコマンド名に基づいてバイナリを検索するのと同じ意味を使用して、特定のファイルの可能な資産ファイルの場所のリストを簡単に検索できるようにしたいと思います。
たとえば、次のようなディレクトリ構造があるとします。
/usr/foo/assets
+- sounds
| +- ding.ogg
| +- dong.ogg
+- images
+- foo.png
/usr/local/foo/assets
+- sounds
| +- ding.flac # better ding
+- images
+- bar.png
私はこのような一種の検索パスを定義し、独自のパスも含めて、私のアセットフォルダの.local
後にfreedesktopのデフォルトサウンドに戻ることを望んでいます。
FOO_SOUNDS_PATH=$HOME/.local/foo/assets/sounds:/usr/local/foo/assets/sounds:/usr/foo/assets/sounds:/usr/share/sounds/freedesktop/stereo
最終的な結果は、パス全体を直接決定するのではなく、基本名のみを使用してファイルを参照できるようにしたいということです。これにより、次のような内容を作成できます。
#!/bin/bash
play_sound(){
paplay $(find_on_path --ext="ogg,wav,mp3,flac" --path="$FOO_SOUNDS_PATH" "$1")
}
play_sound ding # play /usr/local/foo/assets/sounds/ding.flac
play_sound dong # play /usr/foo/assets/sounds/dong.ogg
# fallback to freedesktop system 'complete' sound:
play_sound complete # play /usr/share/sounds/freedesktop/stereo/complete.ogg
便利な例なので、サウンドファイルを使用していますが、システムサウンドを再生する方法については特に興味がなく、より一般的な技術に興味があります。
他の種類のリソースに対して同じ意味を簡単に再利用する方法はありますか$PATH
?では、どうすればよいですか?そうでない場合はどうすればよいですか?
答え1
さて、ここにこれらのアイデアを bash スクリプトや関数でラップする 1 つのアプローチがあります。
$ FOO_SOUNDS_PATH=$HOME/.local/foo/assets/sounds:/usr/local/foo/assets/sounds:/usr/foo/assets/sounds:/usr/share/sounds/freedesktop/stereo
$ IFS=':' read -r -a array <<< "$FOO_SOUNDS_PATH" # IFS splits path into array var by ':'
$ echo "${array[@]}"
$ /home/sparrow/.local/foo/assets/sounds /usr/local/foo/assets/sounds /usr/foo/assets/sounds /usr/share/sounds/freedesktop/stereo
これは、以下を推論できることを意味します。
$ for i in "${array[@]}"; do find $i -type f -name *.ogg -or -name *.wav -or -name *.mp3 -or -name *.flac -printf "%f\n"; done
これにより、関連するサウンドファイルがすべて提供されます。コマンドに従って再生できるように、ファイルを変数として保存するために残りのファイルをスクリプトする必要があります。少なくとも正しい方向を教えてほしい!
答え2
いくつかのバリエーションを試してみてください。
$ cat tst.sh
#!/bin/env bash
assPath='/foo:/bar/whatever:/somewhere/else'
assFind() {
local tgt="$1" dir assArr
IFS=':' read -r -a assArr <<< "$assPath"
for dir in "${assArr[@]}"; do
printf 'Searching "%s"\n' "$dir" >&2
if [[ -e "${dir}/${tgt}" ]]; then
printf '%s/%s\n' "$dir" "$tgt"
return 0
fi
done
return 1
}
assFind 'ding.ogg'
$ ./tst.sh
Searching "/foo"
Searching "/bar/whatever"
Searching "/somewhere/else"
明らかに、これらのディレクトリやファイルは私のシステムには存在しないため、実行時に標準出力はありません。