아래 예제가 제대로 작동할 것이라고 생각했습니다.
$ which -a python python3 pip | xargs -I {} {} --version
No '{}' such file or folder
$ which -a python python3 pip | xargs -I _ _ --version
No '_' such file or folder
$ which -a python python3 pip | xargs -I py py --version
No 'py' such file or folder
하지만 대화형으로 실행하면 전혀 작동하지 않으며 문자열도 교체하지 않습니다. 첫 번째 위치에 대한 특별한 경우에 대한 설명이 매뉴얼 페이지에 표시되지 않습니다. 왜 이것이 작동하지 않습니까?
$ which -a python python3 pip | xargs -I py -p eval py --version
eval ~/.pyenv/shims/python --version?...y
xargs: eval: No such file or directory
이는 올바르게 교체되기 때문에 더욱 놀랍습니다.
처음에 이 주장을 어떻게 사용할 수 있습니까? ... -I py sh -c "py --version"
새로운 하위 프로세스가 생성되므로 사용하고 싶지 않습니다 . 현재 환경에서 명령을 평가하는 방법을 알고 싶습니다.
답변1
존재하다 xargs -I replstr utility arguments
,POSIX 요구 사항replstr
에서만 교체 할 수 있으며 에서는 교체할 수 arguments
없습니다 utility
. GNU는 xargs
이와 관련하여 호환됩니다(busybox는 호환 xargs
되지 않음).
env
이 문제를 해결하려면 다음 유틸리티를 사용할 수 있습니다 .
which -a ... | xargs -I cmd xargs env cmd --version
( xargs
선행 공백, 백슬래시, 작은따옴표, 큰따옴표, 줄 바꿈, 가능한 바이트 시퀀스 또는 입력이 해석되는 방식으로 인해 유효한 문자를 형성하기 위한 차단).
또는 더 나은:
for cmd in (which -a ...)
$cmd --version
end
이렇게 하면 파일 이름에 문제가 있는 문자가 개행 문자로만 제한됩니다.
어쨌든 여기서는 사용할 수도 없고 eval
사용하고 싶지도 않습니다. eval
명령을 실행하는 대신 쉘 코드를 해석하는 데 사용되는 쉘 내장 명령(POSIX 쉘의 특수 내장 명령)입니다. xargs
은 셸에 대한 외부 명령이므로 다음과 같이 셸의 인터프리터를 시작하지 않고는 셸이나 셸의 내장 명령을 실행할 수 없습니다.
which -a ... |
xargs -rd '\n' sh -c 'for cmd do "$cmd" --version; done' sh
내가 아는 한 인라인 스크립트는 매개변수를 허용할 수 없으므로 여기서 sh
대신 사용하세요 . 하지만 여전히fish
fish
아니요eval
우리는 이러한 파일 이름이 쉘 코드로 해석되는 것을 원하지 않기 때문에 여기서 사용하는 것은 의미가 없습니다.
또한 -rd '\n'
GNU 관련이지만 존재하지 않는 문제를 사용하여 -I
모든 줄의 전체 내용을 유틸리티(여기 sh
)에 별도의 인수로 전달합니다.