다음 두 개의 최소 쉘 스크립트를 만들었습니다.
테스트 1
#!/usr/bin/env bash
letterList=$1
for letter in $letterList
do
echo $letter
done
그리고 두 번째
테스트 2
#!/usr/bin/env bash
letterList=$1
test1 $letterList
실행하면 원하는 출력 을 test1 'A B C'
얻은 A
다음 .B
C
그러나 실행하면 발생할 것으로 test2 'A B C'
예상되지만 test1 'A B C'
실제 출력은 A
.
따라서 중첩된 변수 목록이 읽혀지지 않는 것, 즉 실행되는 것처럼 보입니다 test1 A
.
무슨 일이 일어나고 있으며 어떻게 원하는 결과를 얻을 수 있습니까?
추신: 관련이 있다면 OS X를 사용하고 있습니다.
답변1
코드에 목록 변수가 없습니다. 당신은 밧줄을 가지고 있습니다.
test1
따옴표가 없는 확장을 사용하는 호출입니다 $letterList
. 이로 인해 쉘은 해당 값을 공백, 탭 및 줄 바꿈(기본적으로)에서 여러 단어로 분할하고 각 단어에 파일 이름 와일드카드가 포함된 경우 파일 이름 와일드카드가 됩니다. 결과 단어는 test1
별도의 인수로 전달됩니다.
에서는 test1
이러한 매개변수 중 첫 번째를 에 넣습니다 letterList
.
$letterList
문자열을 test1
from as is 에 전달 하려면 test2
호출 시 확장을 큰따옴표로 묶어야 합니다.
test1 "$letterList"
그런데 당신은의지하다$letterList
루프의 값 분할은 셸에서 수행되지만 test1
(문제를 일으키는 동일한 메커니즘) 코드가 실수로 파일 이름 글로빙을 수행하는 것을 방지할 수는 없습니다(예를 들어 스크립트를 테스트하여 test2 "A B C *"
무슨 뜻인지 확인).
합격하고 싶다면목록단일 문자열 대신 test2
문자열 대신 목록을 사용하여 호출합니다.
test2 A B C "Hello World" "* *"
그런 다음 에서 test2
매개변수를 다음으로 전달합니다 test1
.
#!/bin/sh
test1 "$@"
여기에서는 "$@"
위치 인수(스크립트에 대한 매개변수) 목록이 확장되고 각 개별 인수가 참조됩니다. 이는 이와 같은 매개변수가 Hello World
호출 시 여러 매개변수로 분할되지 않고 test1
문자열이 * *
둘로 분할되지 않으며 파일 이름 일치가 발생하지 않음을 의미합니다.
에서 test1
매개변수를 반복합니다.
#!/bin/sh
for arg in "$@"; do
printf '%s\n' "$arg"
done
또는
#!/bin/sh
for arg do
printf '%s\n' "$arg"
done
...또는 매개변수만 인쇄하려는 경우에는
#!/bin/sh
printf '%s\n' "$@"
/bin/sh
여기에는 특정 항목이 없기 때문에 전체적으로 쉘로 사용하고 있습니다 bash
.
답변2
./test2 'a b c'
실행하면 다음을 얻습니다.
$1=a b c
따라서 마지막 줄은 다음과 같습니다.
test1 a b c
실행 하면 test1
다음을 얻습니다:
$1=a
$2=b
$3=c
즉, 주어진 매개변수는 test1
따옴표로 묶이지 않으므로 하나가 아닌 세 개의 매개변수가 됩니다.
test1
단일 매개변수를 전달하려면 변수를 큰따옴표로 묶으면 됩니다. 즉, 마지막 줄을 다음 test2
으로 바꿉니다.
./test1 "$letterlist"
../
.
$PATH
답변3
실제 목표가 무엇인지는 확실하지 않습니다. 당신이 명확하게 말하는 유일한 것은 세 개의 개별 라인 및 에 test2 'A B C'
출력을 원한다는 것입니다 A
.B
C
그러한 결과를 제공할 수 있는 다른 솔루션이 있습니다. 일반적으로 출력은 다음과 비슷해 보입니다. 켈룸의 답변.
test2
동일하게 유지하십시오 .test1
다음과 같이 변경합니다 .#!/bin/sh for letter in $* do printf '%s\n' "$letter" done
그러면 자연스럽게 행동이 바뀔 것입니다
test1
. 이제$1
. 따라서 , , 및 ( 단지 , 및 대신 ) 이test1 'A B C' 'D E F'
6개의 개별 라인에 출력됩니다 .A
B
C
D
E
F
A
B
C
$*
공백이 포함된 문자열을 별도의 단어로 분리하므로 일반적으로 사용을 권장하지 않습니다 . 예를 들어 "lazy dog"
두 단어(매개변수)가 됩니다. 그러나 이것은 정확히 당신이 원하는 행동인 것 같습니다.
printf
echo
파일 이름의 시작 부분보다 약간 안전합니다.-
또는 포함되어 있습니다 \
. 이 사이트에서는 이미 이에 대해 자세히 설명하고 있습니다. 더 알고 싶으시면 검색해 보세요.