당신은 혼란 것으로 보인다.
에서 유닉스, 프로그램을 시작하는 것은 세 가지 매개 변수를 포함한다. rs :
- 파일 이름. 이것은 실행할 프로그램의 경로를 포함하는 문자열입니다.
- 문자열 목록입니다. 규약에 따라이 "명령 행 인수"라고 부릅니다.
- 문자열의 다른 목록입니다. 규칙에 따라 우리는 이것을 "환경"이라 부릅니다. 그러나 OS 레벨에서 이것은 또 다른 문자열 목록 일뿐입니다. 그러나 모든 프로그램/라이브러리는 사용자와 응용 프로그램 프로그래머 모두에게 숨겨 지도록 유지합니다. 당신이 쉘에 명령을 입력 할 때
많은 일들이 발생하지만, 가장 간단한 경우는 공백으로 구분 된 단어의 단지 무리입니다 :
$ foo bar baz
($
은 쉘 프롬프트를 표시하지 뭔가 당신이 입력합니다.) 쉘은 세 단어 (foo
, bar
, baz
)에이 줄을 분할하고 프로그램의 이름으로 첫 번째 해석
합니다 (PATH
V에 나열된 디렉토리에서 조회 할 수 있습니다 ariable). PATH
목록이 /usr/bin
이고 실제로는 /usr/bin/foo
프로그램이 있다고 가정 해 보겠습니다.
exec("/usr/bin/foo", ["foo", "bar", "baz"], [...])
즉 : (의사 코드) 다음과 같이
이제 쉘은 프로그램을 시작합니다
/usr/bin/foo
에 실행 파일을 실행하고 인수로 세 개의 문자열 목록을 전달합니다. (
[...]
은 지금부터 무시할 환경을 나타냅니다.)
이렇게하는 경우 어떻게됩니까?
$ foo "bar baz"
따옴표는 셸이 줄을 단어로 분할하는 방식에 영향을줍니다. 특히 따옴표로 묶인 " "
(공백)은 구분 기호로 사용되지 않고 그대로 사용됩니다. 이렇게하면 두 요소 목록 (foo
, bar baz
)이 표시됩니다. 따옴표는 단어 자체에 포함되지 않습니다.
는 내부적으로이 다음과 같은 호출로 변환 :
exec("/usr/bin/foo", ["foo", "bar baz"], [...])
가 다시 두 번째 인수는 단순히 공간을 포함하고 있습니다. 내장 된 따옴표가 없습니다.
그래서 무슨 일이
$ xargs -pi find ~/Multimedia/Musik/flac/ -name "\""{}"\""
같은 명령됩니까?
이것은 다시 셸에 의해 단어 목록으로 구문 분석됩니다. ~
은 홈 디렉토리의 이름으로 바뀝니다. "\""
은 단지 \"
또는 '"'
(즉, 리터럴 "
문자)를 쓰는 회선 방식입니다. 우리가 끝내는 목록은 xargs
, -pi
, find
, /home/madZeo/Multimedia/Musik/flac/
, -name
, "{}"
입니다. 이것은 다음과 같은 호출로 변환 : 마지막 인수가 4 문자열 "{}"
얼마나
exec("/usr/bin/xargs", ["xargs", "-pi", "find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"{}\""], [...])
참고.
xargs
은 첫 번째 인수 (-pi
)를 옵션 사양으로 처리합니다. 특히 -i
은 인수 목록의 {}
을 표준 입력에서 읽은 현재 값으로 바꿔야한다고 알려줍니다.
xargs
그러면 표준 입력에서 한 행을 읽습니다.이 입력은 (echo
파이프이므로) 01.Here Comes The Night Time II.flac
이됩니다.
이 목록 find
, /home/madZeo/Multimedia/Musik/flac/
, -name
, "01.Here Comes The Night Time II.flac"
을 산출 {}
대신에 대체됩니다. xargs
는이 같은 find
를 호출
이
exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "\"01.Here Comes The Night Time II.flac\""], [...])
이 이름이 그대로 "
(견적 문자)로 시작하는 파일을 찾아 find
을 알려줍니다. 그러한 파일이 없으므로 실패합니다.
수정은 다음과 같이 명령을 작성하는 것입니다 :
$ xargs -pi find ~/Multimedia/Musik/flac/ -name {}
이 궁극적으로 당신이 원하는 인
exec("/usr/bin/find", ["find", "/home/madZeo/Multimedia/Musik/flac/", "-name", "01.Here Comes The Night Time II.flac"], [...])
를 실행 끝납니다.
xargs
의 하위 명령 (이 경우 find
)이 직접 실행됩니다. 쉘이 다시 파싱하는 새로운 명령 행을 생성하지 않습니다. 공백에 들어오는 인수를 분할하지 않고 따옴표를 해석하지 않고 $
또는 *
또는 \
과 같은 특수 문자는 신경 쓰지 않습니다. 주어진 단어의 목록을 취하고 서브 문자열 {}
의 모든 항목을 현재 입력으로 바꾼 다음 실행합니다.
이 최종 명령을 천천히 취하여 쉘에 붙여 넣으면 단어 분리, 따옴표 제거 등을 수행하여 결과가 달라집니다.
'... -name {}'은 어떻게됩니까? – melpomene
"xargs -pi find ~/Multimedia/Musik/flac/-name {}"(-0 옵션없이) 명령을 사용하면 분명히 이것이 시도하지 않은 유일한 조합이었습니다. 그런데 왜 지금 일하고 있습니까? 이렇게하면 xargs의 명령 요청이 발생합니다. "find ~/Multimedia/Musik/flac/-name 01.Here Comes The Night Time II.flac"이 이에 대한 복사 및 붙여 넣기가 작동하지 않습니다. – madZeo
무거운 손으로 제목을 편집하는 것을 용서하십시오. 그러나이 질문을 동일한 오해를 가진 다른 사람들에게로 향하게하는 첫 번째 접근법입니다. 그리고 질문에 정확히 답하는 것에 잠재적으로 관심이있는 사람들에게 명확하게 전달합니다. –