찾기 도구를 사용하여 시스템 경로($PATH)에서 파일을 찾는 방법은 무엇입니까? 또는 검색의 시작점 디렉토리를 표현식으로 어떻게 지정할 수 있습니까?

찾기 도구를 사용하여 시스템 경로($PATH)에서 파일을 찾는 방법은 무엇입니까? 또는 검색의 시작점 디렉토리를 표현식으로 어떻게 지정할 수 있습니까?

예를 들어, 시스템 $PATH의 일부인 모든 디렉터리에서 특정 바이너리를 참조하는 모든 심볼릭 링크를 찾고 싶습니다. 모든 디렉터리를 수동으로 지정하면 이를 성공적으로 수행할 수 있습니다.

sudo find ~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin -lname /opt/openoffice4/program/soffice

하지만 $PATH 확장과 함께 명령을 사용하려고 하면 다음과 같습니다.

sudo find `echo $PATH | tr ':' ' '` -lname /opt/openoffice4/program/soffice

오류와 결과가 나타납니다.

find: ‘~/bin’: No such file or directory
/usr/bin/soffice.link-to-openoffice-bak
echo $PATH | tr ':' ' '

올바른 경로를 출력하십시오.

~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin

다음도 작동하지 않습니다.

sudo find `echo $PATH | tr ':' ' ' | xargs` -lname /opt/openoffice4/program/soffice
sudo find { `echo $PATH | tr ':' ' ' | xargs` } -lname /opt/openoffice4/program/soffice
sudo find eval "echo $PATH | tr ':' ' ' | xargs" -lname /opt/openoffice4/program/soffice
echo $PATH | tr ':' ' ' | xargs | sudo find -lname /opt/openoffice4/program/soffice  # runs some long computation

starting point디렉토리를 계산된 매개변수로 어떻게 전달할 수 있나요 find? 가능합니까?

답변1

이미 액세스 권한이 있는 디렉터리를 포함해야 하므로 sudo사용할 필요가 없습니다 .$PATH

이 문자는 ~쉘 및 기타 쉘의 홈 디렉토리에 대해 내장된 바로가기입니다. bash그러나 귀하의 예에서 사용할 수 있을 만큼 늦게 평가되지는 않았습니다. (인용된 표현식 내에서도 평가되지 않습니다.)

을 설정할 때 $PATH이와 같은 것을 사용하는 대신 PATH=~/bin:$PATH보다 명시적인 대안을 사용하는 것을 고려해 보십시오 PATH="$HOME/bin:$PATH".

일부 코드의 경우 디렉터리 이름의 공백을 처리하는 $PATH대체 솔루션은 다음과 같습니다.

( IFS=:; for p in $PATH; do [ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'; done )

더 읽기 쉽고,

(
    IFS=:
    for p in $PATH
    do
        [ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'
    done
)

답변2

리터럴을 $PATH포함하면 마치 를 실행한 것처럼 현재 작업 디렉터리에서 literal이라는 디렉터리의 하위 디렉터리에서만 실행 파일을 찾을 수 있습니다 .~/binbin~mkdir -p '~/bin'

그건 ~/bin거짓이므로 제거해야 합니다.

실행하는 경우:

PATH=~/bin:$PATH

참조가 없으면 출력을 ~찾을 수 있습니다 .printf '%s\n' "$PATH"

/home/you/bin:~/bin:/home/samokat/.local/bin:/home/samokat/bin:...

이것은 홈 디렉토리 ~/bin로 적절하게 확장되고 , 그 뒤에 이미 존재하는 가짜 파일과 .bin~/binPATH

그러나 you실제로 가정하면 samokat이는 디렉토리가 두 번 나타나며 $PATH그 중 하나는 중복됨을 의미합니다.

모든 디렉토리 구성요소의 파일을 $PATH수정 한 후에는 필요한 모든 것이 갖추어져 있습니다.find$PATHbash

(IFS=:; set -o noglob; find -H $PATH -lname /opt/openoffice4/program/soffice)

특수 매개변수는 $IFS따옴표가 없는 매개변수 확장이 분할되는 방식을 결정합니다. 기본적으로 $IFS공백 문자(줄 바꿈 및 탭 포함)가 포함되어 s 변경이 :작동하는 이유를 설명하지만 올바른 값으로 설정하는 것이 좋습니다 . IFS또한 set -o noglob비활성화하는 것에 유의하세요.다른인용되지 않은 매개변수 확장의 부작용.

또한 -H이것이 없으면 find실제로 디렉터리 심볼릭 링크인 디렉터리는 표시되지 않습니다.

또는 배열 바인딩으로 전환할 수 있는 경우 zsh(예: in)는 다음과 같습니다.$PATH$pathcsh

find -H $path -lname /opt/openoffice4/program/soffice

에서는 zsh대신 glob을 사용할 수도 있습니다 find.

예를 들어:

print -rC1 -- $^path/*(N@e['[[ $REPLY:P = /opt/openoffice4/program/soffice ]]'])

print rolumn의 실제 항목은 각 구성 요소 내의 1 C심볼릭 링크() 경로 가 됩니다 .@$pathP/opt/openoffice4/program/soffice

관련 정보