교대조 1을 호출한 후 교대조 인수 취소

교대조 1을 호출한 후 교대조 인수 취소

이 시나리오가 있습니다

first_arg="$1";

if foo; then
    shift 1;
    node foo.js "$@"

elif bar; then

   shift 1;
    node bar.js "$@"

elif baz; then

   shift 1;
   node baz.js "$@"

else

   node default.js "$@"

fi

위의 내용을 다음과 같이 변경하고 싶습니다.

first_arg="$1";
shift 1;

if foo; then

    node foo.js "$@"

elif bar; then

    node bar.js "$@"

elif baz; then

   node baz.js "$@"

else

   unshift 1;
   node default.js "$@"

fi

그런데 unshift 같은 연산자가 있는지는 잘 모르겠어서 그냥 만들어봤습니다. 해결 방법은 다음과 같습니다.

node default.js "$first_arg" "$@"

그런데 이렇게 하려고 하면 이상하게 행동합니다.

답변1

shift 1첫째, 를 사용할 필요가 없습니다. 위치 매개변수를 사용하고 해당 인덱스를 분할하여 매개변수를 전달하면 됩니다.

first_arg="$1"

이 작업이 완료되면 나머지 매개변수는 로 액세스할 수 있습니다 "${@:2}". 이 표기법은 위치 인수 2를 목록 끝까지 나타내는 방법입니다.

귀하의 예를 사용한 구성은 다음과 같습니다.

node foo.js "${@:2}"

마지막 else부분에서는 다음을 수행합니다.

node default.js "$1" "${@:2}"

"$@"이는 위치 매개변수 변환이 없는 것과 동일합니다.

답변2

매개변수를 배열에 저장할 수 있습니다.

args=( "$@"  )  # use double quotes
shift 1

if foo; then
  node foo.js "$@"
elif bar; then
  node bar.js "$@"
elif baz; then
  node baz.js "$@"
else
  node default.js "${args[@]}"
fi

답변3

당신이 시도한 것들:

first_arg=$1
shift

# ...later...

else
    node default.js "$first_arg" "$@"
fi

명령줄 인수가 하나 이상 있는 경우 첫 번째 변형과 동일합니다.

명령줄 인수가 없으면 "$first_arg"여전히 빈 문자열이므로 인수가 되며 "$@"빈 문자열은 생성되지도 않습니다.

Node 애플리케이션이 명령줄에서 빈 매개변수를 허용하는 경우 애플리케이션이 두 가지 코드 변형에서 다르게 동작할 수 있습니다.

명령줄 인수 없이 스크립트를 호출하는 것이 유효한 방법이라면 다음을 수행할 수 있습니다.

node default.js ${first_arg:+"$first_arg"} "$@"

${first_arg:+"$first_arg"}first_argis가 비어 있거나 설정되지 않은 경우 where는 비어 있는 상태로 확장되지만, 비어 있지 않은 문자열로 설정된 "$first_arg"경우 비어 있는 상태로 확장됩니다. first_arg또는 설정되지 않았거나 비어 있는 변수에 대해 명시적인 오류를 발생시키려는 경우:

node default.js "${first_arg:?Error, no command line arguments}" "$@"

대안 에는 배열 $@로 복사가 포함됩니다.bashJesse_b가 그의 답변에서 보여주듯이.

다시 $first_arg넣어$@

set -- "$first_arg" "$@"

명령줄 인수가 $1누락된 것처럼 빈 인수가 포함되므로 작동하지 않습니다 .$@

그리고

set -- ${first_arg:+"$first_arg"} "$@"

$first_arg비어 있거나 변수가 존재하지 않으면 "이동되지 않은" 항목이 없습니다.


shift동일하고 shift 1단일 명령문은 ;Except로 끝날 필요가 없으며 같은 줄에 있는 다른 명령문 뒤에 올 필요가 없습니다(개행 문자는 그와 마찬가지로 명령 종결자입니다 ;).

관련 정보