$PATH
편집하려는 파일의 스크립트를 가리키는 심볼릭 링크가 있습니다. 파일 경로를 잊어버려서 다음을 시도해 보았습니다.
$ which my_script_link | readlink
출력 파일 경로를 예상했지만 출력됩니다.
> readlink: missing operand
> Try 'readlink --help' for more information
이전에 다른 상황(예: 편집을 위해 파일 목록을 vim으로 파이프하는 등)에서도 유사한 동작을 본 적이 있습니다. subshell 과 같은 해결 방법이 있다는 것을 알고 있지만 readlink $(which my_script_link)
이해하고 싶습니다.왜이 경우 파이프라인이 내가 상상한 대로 작동하지 않습니다.
감사해요!
답변1
간단히 말해서, 이를 수행하도록 프로그램이 작성되지 않았기 때문입니다. 소프트웨어가 STDIN에서 읽을 수 있는지 또는 입력 파일이 필요한지 여부를 결정하는 것은 프로그래머의 몫입니다. 이 경우 readlink
해당 man
페이지에는 다음과 같이 명시되어 있습니다(강조).
readlink - 인쇄가 해결됨심볼릭 링크또는 규범적인파일 이름
요약
읽기 링크 [옵션]...문서...
일반적으로 STDIN에서 입력을 받는 프로그램은 어떤 방식으로든 해당 입력을 구문 분석하도록 설계되었습니다. 데이터를 파이프하면 readlink
텍스트 스트림을 수신하지만 내용이 아닌 파일만 처리하기 때문에 어떻게 해야 할지 모릅니다. ls
또는 cd
와 같은 프로그램도 마찬가지입니다 cp
. 텍스트/데이터 스트림을 처리하는 프로그램만 파이프의 입력을 받아들일 수 있습니다.
답변2
프로그램이 stdin
명령줄 인수에서 입력을 받거나 명령줄 인수로 입력을 받는지는 디자이너에게 달려 있습니다. 두 가지 방법 모두 장점이 있습니다. 그러나 파일을 엄격하게 조작하는 프로그램의 경우 파일 이름을 명령줄 인수로 전달하는 것이 일반적으로 stdin
.
가장 분명한 이유는 파일에서 프로그램을 실행하는 일반적인 경우에는 . readlink file
대신 : 을 입력하는 것이 더 쉽다는 것입니다 echo file | readlink
.
더 미묘한 문제는 정확성입니다. 문제는 파일 이름이 를 통해 전달될 때 stdin
프로그램이 하나의 파일 이름을 다른 파일 이름과 구별할 수 있어야 한다는 것입니다. 일반적으로 이는 파일 이름이 공백이나 개행 문자로 구분되어 있다고 가정하여 수행되지만 파일 이름에 공백이 포함될 수 있으므로 이는 올바르지 않습니다. 더 나은 접근 방식은 null 바이트를 사용하여 파일 이름을 구분하는 것이지만, null 바이트로 구분된 파일 목록을 생성하는 것은 불편할 수 있습니다.
명령줄에 파일 이름을 전달하면 쉘이 프로그램의 모든 구문 분석 및 참조를 처리하므로 이 문제를 피할 수 있습니다. 이를 입력하면 touch $'foo\nbar'
특별한 touch
구문 분석이나 인용 자체를 처리할 필요 없이 개행 문자가 포함된 파일 이름으로 올바르게 처리됩니다.
즉, stdin
특정 프로그램에 대한 파일을 전달하려는 경우 그렇게 할 수 있습니다. 그것이 xargs
목적입니다. xargs
명령줄의 인수만 받아들이고 이를 통과시키는 프로그램을 사용할 수 있습니다 stdin
.
즉, 다음을 수행할 수 있습니다 which my_script | xargs readlink
.
항상 이런 방식으로 작업하려면 readlink
별칭을 만들 수 있습니다 alias readlink="xargs readlink"
. 이렇게 하면 원래 원했던 방식으로 들어갈 수 있습니다 which my_script | readlink
.
답변3
STDIN을 통해 인수를 가져오지 않는 명령의 경우 다음 코드 pragma를 사용할 수 있습니다.
$ readlink $(which my_script_link)
예
$ ln -s /bin/ls ~/bin/somecmd
이제 거기에 있는지 확인하십시오 $PATH
.
$ which somecmd
~/bin/somecmd
또는 선호하는 방법은 type
다음을 대신 사용하는 것입니다 which
.
$ type somecmd
somecmd is /home/saml/bin/somecmd
아니면 그냥 값:
$ type -P somecmd
/home/saml/bin/somecmd
이제 다음을 실행합니다 readlink
.
$ readlink $(type -P somecmd)
/bin/ls