나는 쉘 스크립트에서 이 줄을 이해하려고 노력하고 있습니다. 이는 $(..)
실행 하고 명령문에서 ..
찾은 위치에 출력을 삽입한다는 의미 라는 것을 알고 있습니다 . $()
그런데 그 괄호 사이에는 무슨 일이 벌어지고 있는 걸까요? 수행 중인 작업 은 무엇 이며 이전 행의 \ls
작업과 어떤 관련이 있습니까 ? 두 줄로 나누어진 \
건가요 ? 일반이랑 똑같 \\
나요 ?\ls
ls
APPCLASSPATH=$CLASSPATH:$({ \
\ls -1 "$VOLTDB_VOLTDB"/voltdb-*.jar; \
\ls -1 "$VOLTDB_LIB"/*.jar; \
\ls -1 "$VOLTDB_LIB"/extension/*.jar; \
} 2> /dev/null | paste -sd ':' - )
답변1
3개 명령의 출력은 이를 값으로 병합하는 명령 ls
으로 전달됩니다 .paste
$VOLTDB_VOLTDB"/voltdb-*.jar:$VOLTDB_LIB"/*.jar:$VOLTDB_LIB"/extension/*.jar
메모:변수 $VOLTDB_VOLTDB
및가 $VOLTDB_LIB
확장되며 이러한 각 ls
명령에 대해 하나의 파일보다 더 많은 값이 있을 수 있습니다. 저기 보이나요 *
? 예를 들어 이는 와일드카드 역할을 하고 왼쪽(voltdb-)과 오른쪽(.jar) 사이의 모든 항목으로 확장되는 glob 문자입니다.
이는 다음과 일치합니다.
voltdb-1.jar
voltdb-blah.jar
voltdb-12345.jar
그러면 모든 것이 변수에 포함됩니다 APPCLASSPATH
.
APPCLASSPATH=$CLASSPATH:$VOLTDB_VOLTDB"/voltdb....etc.
붙여넣기 명령
seq
다음은 명령을 사용하여 1-10의 일련의 숫자를 생성하는 예입니다 .
$ seq 10 | paste -sd ':' -
1:2:3:4:5:6:7:8:9:10
paste
명령이 출력을 병합하고 콜론( )으로 구분하는 것을 볼 수 있습니다 :
.
다음과 같이 예제 명령을 흉내낼 수도 있습니다.
$ { echo "hi1"; echo "hi2"; echo "hi3"; } | paste -sd ':' -
hi1:hi2:hi3
메모:붙여넣기 명령 은 -
STDIN에서 입력을 가져와 입력된 대로 각 인수를 :
.
다른 스위치를 사용하면 뒤에 오는 ' paste
의 수에 따라 데이터를 그룹으로 분할할 수도 있습니다 .-
붙여넣기 예
다음은 2 의 예입니다 -
.
$ seq 10 | paste - -
1 2
3 4
5 6
7 8
9 10
여기 3 -
이 있습니다.
$ seq 10 | paste - - -
1 2 3
4 5 6
7 8 9
10
따라서 각 줄에 paste
몇 개의 인수를 인쇄해야 하는지 알려줍니다 . paste
그러나 혼동하지 마십시오. 여러분이 다루고 있는 예는 단순히 STDIN에서 입력을 가져와서 각 인수를 공백으로 구분하고 그 뒤에 :
. 여러 개의 -
'를 제공할 때 paste
인수를 2개와 한 번, 한 번에 3개 등으로 취하라는 뜻입니다.
한 번에 2개의 인수를 :
'로 구분합니다.
$ seq 10 | paste -d ':' - -
1:2
3:4
5:6
7:8
9:10
$ seq 10 | paste -d ':' - - -
1:2:3
4:5:6
7:8:9
10::
덧붙여서, 스위치를 포함하면 인수를 직렬로 취하도록 -s
지시하는 것입니다 . paste
위의 예 중 하나에서 이를 사용하면 어떤 일이 발생하는지 살펴보세요.
한 번에 2개:
$ seq 10 | paste -sd ':' - -
1:2:3:4:5:6:7:8:9:10
한 번에 3개:
$ seq 10 | paste -sd ':' - - -
1:2:3:4:5:6:7:8:9:10
답변2
$(command)
명령을 실행하고 해당 출력을 대체합니다.
{ list; }
현재 쉘 환경에서 여러 명령을 실행하는 그룹 명령입니다. 와 비슷 (list)
하지만 서브쉘을 만들지 않습니다.
\command
명령에 대한 별칭을 무시하는 데 사용되며, 이로 인해 명령 예상 동작이 크게 변경될 수 있습니다.
줄의 끝 은 \
단순히 이 줄이 계속된다는 것을 의미하므로 쉘은 다음 줄을 현재 줄의 일부로 간주합니다. 문맥상(여는 괄호 또는 인용문)에서 이것이 명백할 경우 일반적으로 필요하지 않습니다.
답변3
APPCLASSPATH=$CLASSPATH:$({ \ \ls -1 "$VOLTDB_VOLTDB"/voltdb-*.jar; \ \ls -1 "$VOLTDB_LIB"/*.jar; \ \ls -1 "$VOLTDB_LIB"/extension/*.jar; \ } 2> /dev/null | paste -sd ':' - )
\ls
은 별칭인 ls
경우 백슬래시가 별칭 확장을 방지한다는 점을 제외하면 와 같습니다 . ls
이렇게 하면 ls
분류자 접미사( )와 같이 원치 않는 출력을 추가할 수 있는 별칭이 아닌 명령이 사용된다는 것을 보장합니다 -F
.
ls
기존 파일 이름을 인수로 사용하여 호출되는 명령은 해당 인수를 한 줄에 하나씩 나열합니다 . -1
출력이 ls
터미널이 아닌 파이프로 진행되므로 이 옵션은 효과가 없습니다. ls
기존 파일의 이름이 아닌 인수를 받으면 표준 출력에 아무것도 표시하지 않고 대신 오류를 표시합니다 . 명령 의 오류는 ls
에 의해 아무데도 리디렉션되지 않습니다 2> /dev/null
. 파일이 아닌 인수를 받는 데에는 두 가지 이유가 있습니다 ls
. 변수 중 하나가 기존의 읽을 수 있는 디렉터리를 참조하지 않거나 와일드카드 패턴과 일치하는 파일이 없는 경우입니다. 두 경우 모두 패턴은 확장되지 않은 상태로 에 전달됩니다 ls
.
줄 끝의 백슬래시로 인해 쉘은 다음 개행을 무시합니다. 사용되는 모든 지점에서 쉘은 선택적 개행을 기대하기 때문에 여기서는 그 중 어느 것도 유용하지 않습니다.
중괄호 { … }는 명령을 그룹화합니다. 복합 명령이 { \ls …; \ls …; \ls … ; }
파이프로 연결 paste
되고 해당 오류가 로 리디렉션됩니다 /dev/null
.
이 paste
명령은 사이에 를 사용하여 모든 입력 행을 결합합니다 :
. 끝에 tr '\n' :
a를 넣지 않는다는 점을 제외 하면 와 동일합니다 .:
명령 대체를 사용하면 $(…)
의 출력 paste
이 로 보간 됩니다 APPCLASSPATH
. 변수 값 뒤에 CLASSPATH
콜론을 사용하여 두 부분을 구분합니다.
다음은 단순화된 버전입니다. 일치하는 와일드카드 패턴이 없으면 추가 후행 콜론이 없는 APPCLASSPATH
것과 동일하다는 점에서 원본과 약간 다릅니다 CLASSPATH
(바람직함).
APPCLASSPATH=$CLASSPATH:$(
\ls "$VOLTDB_VOLTDB"/voltdb-*.jar "$VOLTDB_LIB"/*.jar "$VOLTDB_LIB"/extension/*.jar |
tr '\n' :) 2>/dev/null
APPCLASSPATH=${APPCLASSPATH%:}