다른 스크립트와 함께 실행 파일을 사용하고 있었는데 /usr/bin/foo
조금 이상하게 동작했기 때문에 동일한 파일 이름을 가진 Bash 래퍼를 만들고 /usr/local/bin/foo
그 안에서 잘못된 동작을 수정했습니다. 내 PATH
것은 /usr/local/bin:/usr/bin
. 래퍼 스크립트에서는 무한 루프에 빠지지 않도록 절대 경로를 통해 원본 실행 파일을 실행해야 합니다.
$ cat /usr/local/bin/foo
#/bin/zsh
/usr/bin/foo | grep -v "^INFO" # reduce output
foo
next in 을 실행하는 간단한 방법(아마도 Zsh 또는 Bash 특정)이 있습니까 PATH
? 즉, current 가 실행되는 디렉토리 다음의 디렉토리에서 foo
원래 실행 파일의 절대 경로를 사용할 필요가 없습니까?PATH
foo
나는 그것을 위한 함수를 만들 수 있습니다 /etc/zshenv
. 별거 아닙니다. 혹시 기준이 있는지 알고 싶습니다. 별칭을 사용하거나 원본 실행 파일을 복구하고 싶지 않습니다.
편집 1: = $ cat /usr/local/bin/foo #/bin/zsh path=(${path/#%$0:A:h}) foo | grep -v "^INFO" # 출력 줄이기
이렇게 하면 현재 실행 파일( )의 절대( ) 디렉터리( )와 정확히 일치하는( ) PATH( )의 ${path/...}
모든 문자열이 지워집니다(그러나 보존됩니다). 솔직히 말해서 StackExchange에서 조립했지만 완전히 이해하지는 못했습니다. 나는 그것이 나를 물지 않기를 바랍니다.#%
:A
:h
$0
편집 2:
$ cat /usr/local/bin/foo
#/bin/zsh
path[${path[(i)$0:A:h]}]=() foo | grep -v "^INFO" # reduce output
$path[(i)foo]
foo
배열의 인덱스를 찾 path
거나 1에 배열 길이를 더한 값을 찾습니다.
답변1
스크립트가 있는 디렉터리( $0:h
zsh, "${0%/*}"
in sh )를 찾아 해당 디렉터리에서 삭제할 수 있습니다 PATH
( path=(${path:#$0:h})
zsh,sh에서 더 복잡함. 동일한 디렉터리가 두 번 포함 되면 PATH
(예: 기호 링크를 통해) 이 작업이 실패할 수 있습니다.
직접 접근 방식의 단점은 경로에서 디렉터리가 제거되지만 동일한 디렉터리에 있는 다른 프로그램이 이상적일 수 있다는 것입니다. 경로 찾기에 수정된 경로만 사용하면 이 문제를 해결할 수 있습니다.
next=$(path=(${path:#$0:h}); print -lr -- =$0:t)
$next
대신 PATH
수동으로 조회를 수행하고 실행 중인 스크립트를 건너뜁니다.
for d in $path; do
if [[ -x $d/$0:t && ! $d/$0:t -ef $0 ]]; then
exec $d/$0:t
fi
done
답변2
예: 사용자 정의 별칭과 실제 명령을 인쇄하려면
$ HOME/bin/에 다른 명령을 추가하면 순서대로 별칭이 표시되고 그 다음에는 PATH가 있는 항목이 표시됩니다. 같은 순서.type -a egrep
egrep
egrep
$ CD # 집에 가세요 $ mkdir -p 빈 $PATH=$HOME/bin:$PATH $ 유형-a egrep egrep의 별칭은 `egrep --color=auto'입니다. egrep은 /bin/egrep입니다. $ echo -e >bin/egrep '#!/bin/bash\necho TEST' $ chmod 755 bin/egrep $ 유형-a egrep egrep의 별칭은 `egrep --color=auto'입니다. egrep은 /home/$USER/bin/egrep입니다. egrep은 /bin/egrep입니다. # /home에 없고 별칭도 아닌 유일한 항목이라고 확신한다고 가정 $ 유형 -a egrep | grep -Ev '/home|alias' |cut -d''-f3 /bin/egrep $ rm $HOME/bin/egrep
답변3
다음을 수행할 수 있습니다.
#! /bin/zsh -
# find the other occurrences of a command with the same name in $path that
# are a different file
other_mes=(
${^path/#%/.}/$0:t(N*^e['[[ $REPLY -ef $0 ]]'])
)
if (( ! $#other_mes )) {
print -ru2 Could not find any other $0:t in PATH.
exit 1
}
# run the first found
$other_mes[1] "$@" | grep -v '^INFO'
# return the exit status of the other me, not of grep
exit $pipestatus[1]
${path/#%/.}
$path
빈 요소를 다음으로 대체하십시오..
$0:t
: 꼬리(기본 이름)$0
[[ a -ef b ]]
a
b
및 가 동일한 파일에 대한 2개의 경로이기 때문에 심볼릭 링크 확인 후 동일한 파일인 것으로 확인되면 true를 반환합니다(예 : 또는 에 대한 심볼릭 링크 이거나 또는 서로에 대한 하드 링크 또는 심볼릭 링크이기 때문에 vs/usr/bin/foo
) ./bin/foo
/bin
/usr/bin
../bin/foo
$PWD
/usr/local
/usr/foo/../bin/foo
sh
구문(및 가장 지원되는 구현)을 사용 [
하고 개행 문자로 끝나지 않는다고 가정하면 다음과 같을 수 있습니다.-ef
$0
#! /bin/sh -
other_me=$(
me=$(dirname -- "$0")
IFS=:; set -o noglob
for dir in $PATH''; do
other_me=${dir:-.}/$me
if [ -x "$other_me" ] && [ -f "$other_me" ] && [ ! "$other_me" -ef "$me" ]; then
printf '%s\n' "$other_me"
exit
fi
done
printf>&2 '%s\n' "Cound not find any other $me in PATH."
exit 1
) || exit
{
exit_status=$(
{
{
"$other_me" "$@" 4>&-
echo "$?" >&4 4>&-
} 3>&- | grep -v '^INFO' >&3 3>&- 4>&-
} 4>&1
)
} 3>&1
exit "$exit_status"
끝에 있는 복합 비트에 의해 획득된 종료 상태입니다 $other_me
.