Perl 문서에서는페렌(1)Perl 스크립트를 실행하려면 이중 언어 쉘/Perl 헤더를 사용하는 것이 좋습니다.
#!/bin/sh
#! -*-perl-*-
eval 'exec perl -x -wS $0 ${1+"$@"}'
if 0;
무슨 뜻이에요 ${1+"$@"}
? (Bash를 /bin/sh로 사용) 사용해 보았는데 "$@"
잘 작동하는 것 같았습니다.
편집하다
아래 두 가지 답변은 ${1:+"$@"}
. 나는 ${parameter:+word}
bash(1)에 문서화된 ("대체 값 사용") 구문을 알고 있습니다. 그러나 나는 그것을 믿지 않는다. 왜냐하면
${1+"$@"}
매개변수 없이도 둘 다 잘 작동합니다."$@"
simple.sh를 다음과 같이 생성하면#!/bin/sh eval 'exec /usr/bin/perl -x -S -- $0 "$@"' if 0; #!perl use Data::Dumper; print Dumper(\@ARGV);
그리고 Question.sh는 다음과 같습니다.
#!/bin/sh eval 'exec /usr/bin/perl -x -S -- $0 ${1+"$@"}' if 0; #!perl use Data::Dumper; print Dumper(\@ARGV);
둘 다 같은 방식으로 작동하게 할 수 있습니다.
$ ./question.sh $VAR1 = []; $ ./question.sh a $VAR1 = [ 'a' ]; $ ./question.sh a 'b c' $VAR1 = [ 'a', 'b c' ]; $ ./question.sh "" $VAR1 = [ '' ]; $ ./simple.sh $VAR1 = []; $ ./simple.sh a $VAR1 = [ 'a' ]; $ ./simple.sh a 'b c' $VAR1 = [ 'a', 'b c' ]; $ ./simple.sh "" $VAR1 = [ '' ];
다음을 포함하여 인터넷의 다른 소스도 사용됩니다
${1+"$@"}
.해커자기가 무슨 짓을 하는지 아는 것 같았던 사람.
${parameter+word}
문서화되지 않은 대체(또는 더 이상 사용되지 않는) 구문 일까요 ${parameter:+word}
? 이 가설을 확인할 수 있는 사람이 있나요?
답변1
이는 Bourne 쉘과의 호환성을 위한 것입니다. Bourne 쉘은 1979년 Unix 버전 7과 함께 처음 출시되었으며 /bin/sh
1990년대 중반까지 대부분의 상용 Unices에서 일반적으로 사용되었던 고대 쉘입니다.
대부분의 사람들의 조상이다.본 같은 껍질ksh
, 또는 .bash
zsh
ksh
여기에는 몇 가지 어색한 기능이 있으며 그 중 많은 기능이 다른 쉘 및 새로운 표준 사양에서 수정 되었습니다 sh
. 그 중 하나는 다음과 같습니다.
Bourne 쉘의 경우(적어도 아직 수정되지 않은 변형): 인수가 전혀 없는 대신 "$@"
위치 인수 목록이 비어 있으면( $# == 0
) 빈 인수로 확장합니다.
${var+something}
$var
설정되지 않은 경우 '무언가'로 확장됩니다. 모든 쉘에 명확하게 문서화되어 있지만 bash
다음 문장에 주의를 기울여야 하기 때문에 문서에서 찾기가 어렵습니다 .
하위 문자열 확장이 수행되지 않으면 bash는 아래 문서화된 형식을 사용하여 설정되지 않았거나 null인 인수를 테스트합니다. 콜론을 생략하면 설정되지 않은 매개변수만 테스트됩니다..
${1+"$@"}
따라서 Bourne 쉘의 제한 사항을 해결하는 ( ) 설정 시에만 확장됩니다 ."$@"
$1
$# > 0
Bourne 쉘은 이 문제가 있는 유일한 쉘입니다. 최신 s( POSIX 사양을 sh
준수함 (Bourne 쉘은 그렇지 않음))에는 이 문제가 없습니다. 따라서 매우 오래된 시스템에서 작동하는 코드가 필요한 경우에만 이 작업을 수행하면 됩니다. 표준 쉘 대신 Bourne 쉘이 될 수 있습니다(POSIX는 표준이 어디에 있는지 지정하지 않으므로 예를 들어 Solaris 11 이전의 Solaris에서는 , 여전히 Bourne 쉘(특정 문제는 아니지만), 일반/표준 은 다른 위치( )에 있습니다.sh
sh
/bin/sh
sh
/bin/sh
sh
/usr/xpg4/bin/sh
Perldoc 페이지가 참조되지 않는데 perlrun
문제가 있습니다.$0
바라보다http://www.in-ulm.de/~mascheck/various/bourne_args/더 많은 정보를 알고 싶습니다.
답변2
둘 사이에는 다음과 같은 차이점이 있습니다.
command ""
그리고
command
어떤 경우에는 전달하는 인수가 빈 문자열입니다. 두 번째에서는 0개의 인수가 전달됩니다.
두 경우 모두 "$@"는 다음과 같습니다 ""
. 하지만 사용은 첫 번째 항목에 대한 ${1:+"$@"}
것이며 ""
두 번째 항목에는 매개변수가 전달되지 않습니다. 이것이 의도입니다.
대화형 셸을 얻기 위해 선택적 명령을 사용하거나 인수 없이 호출할 수 있는 아래 스크립트(sshwrapper라고 함)를 실행하는 경우 이는 중요합니다.
: sshwrapper [command]
exec /usr/bin/ssh "${HOSTNAME:-localhost}" "$@"
이는 대화형 쉘이 아닌 원격 호스트(반환만)에서 "" 실행을 시도합니다.
: sshwrapper [command]
exec /usr/bin/ssh "${HOSTNAME:-localhost}" ${1:+"$@"}
exec가 변수를 빈 문자열이 아닌 null로 올바르게 해석하기 때문에 대화형 셸이 원격 호스트에서 시작됩니다.
"${parameter:+word}"("대체 값 사용") 및 유사한 변수 확장 문자열의 사용법은 bash 매뉴얼 페이지를 읽어보세요.
답변3
나는 Stéphane Chazelas의 답변을 요약했습니다.
- ${1:+"$@"}' $1이 비어 있는지 또는 설정되지 않았는지 테스트합니다.
- ${1+"$@"}'는 $1이 설정되지 않았는지 테스트합니다.
그래서 두 번째 매개변수 ""를 사용하면 $1이 비어 있다는 뜻인데 비어 있는지 테스트하지 않고 설정된 것으로만 보고 비어 있으면 $@을 확장하게 됩니다. ""와 함께 ${1:+"$@"}'를 사용하면 더 이상 확장되지 않습니다 $@
.