Bash를 통해 다음과 같이 명령을 실행하고 싶다고 가정 해 봅시다.
/bin/bash -c "ls -l"
Bash 매뉴얼 페이지에 따르면 다음과 같이 실행할 수도 있습니다.
# don't process arguments after this one
# | pass all unprocessed arguments to command
# | |
# V V
/bin/bash -c ls -- -l
작동하지 않는 것만 제외하고는 무시됩니다. 내가 잘못하고 있거나 맨 페이지를 잘못 해석하고 있습니까?
사람의 관련 인용문 :
-c 옵션이 있으면 문자열에서 명령을 읽습니다. 문자열 뒤에 인수가 있으면 $ 0부터 위치 매개 변수에 지정됩니다.
과
A-옵션의 끝을 알리고 추가 옵션 처리를 비활성화합니다. -다음의 인수는 파일 이름과 인수로 취급됩니다.
답변
매뉴얼 페이지를 잘못 해석하고 있습니다. 첫째, --
옵션의 끝을 알리는 부분은 당신이하려는 일과 관련이 없습니다. -c
오버라이드 (override)는이 의미 모두에서 배쉬의 옵션 처리를 통해 더 이상 것입니다 그래서 그 시점에서 명령 행의 나머지 --
명령에 전달 될 수는 옵션 마커의 끝으로 bash에 의해 처리되지.
두 번째 실수는 추가 인수가 명령에 인수로 전달되지 않고 실행되는 쉘 프로세스에 위치 매개 변수로 지정된다는 것입니다. 따라서 수행하려는 작업은 다음 중 하나로 수행 할 수 있습니다.
/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar
첫 번째 경우에는 매개 변수를 전달 $0
하고 $1
명시 적으로 두 번째 경우에는 "$@"
“$ 0을 제외한 모든 위치 매개 변수”처럼 정상적으로 확장 하는 데 사용 합니다. 이 경우에도 사용할 것을 전달해야 $0
합니다. 나는 그것이 $0
일반적으로있을 것이기 때문에 “bash”를 선택 했지만 다른 것은 효과가 있습니다.
그 이유에 관해서는 대신 당신이 목록 명령에 직접 줄 인수를 전달하는, 이런 식으로 이루어집니다 : 문서는 “명령 말한다 참고 (S)가 복수의 문자열에서 읽습니다.” 즉,이 체계를 통해 다음을 수행 할 수 있습니다.
/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file
그러나 원래 목표를 달성하는 더 좋은 방법 env
은 bash
다음 보다는 사용 하는 것입니다 .
/usr/bin/env -- "ls" "-l"
쉘이 제공하는 기능이 필요하지 않으면 사용할 이유가 없습니다 env
.이 경우 사용하는 것이 더 빠르고 간단하며 타이핑이 줄어 듭니다. 그리고 쉘 메타 문자 나 공백을 포함하는 파일 이름을 안전하게 처리 할 수 있다고 생각할 필요는 없습니다.
답변
나는 당신의 목표가 무엇인지 확실하지 않지만, 당신이 단순히 Rube Goldberg 기계 를 만들려고한다면 –“고의로 매우 간단한 작업을 수행하기 위해 의도적으로 과도하게 엔지니어링되거나 과도하게 사용되는 장치, 발명, 장치 또는 장치 복잡한 패션”– 다음 시도
sh -c 'ls $0' -l
또는
sh -c 'ls $1' supercalifragilisticexpialidocious -l
또는
sh -c 'ls -$0' l
이것들은 godlygeek의 답변에서 어떻게 작동하는지 이해할 수 있어야합니다.