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 스크립트나 함수로 래핑할 수 있는 한 가지 접근 방식이 있습니다.
$ 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"
분명히 이러한 디렉터리나 파일은 내 시스템에 존재하지 않으므로 실행할 때 표준 출력이 없습니다.