{} 및 여러 `\ls`를 사용한 복잡한 명령 대체 이해

{} 및 여러 `\ls`를 사용한 복잡한 명령 대체 이해

나는 쉘 스크립트에서 이 줄을 이해하려고 노력하고 있습니다. 나는 이것이 명령문에서 발견된 위치 $(..)에 출력을 실행하고 삽입한다는 것을 의미한다는 것을 알고 있습니다. 그런데 이 괄호 사이에는 무슨 일이 일어날까요? 이것은 무엇을 합니까? 이전 내용과 어떤 관련이 있나요 ? 이게 두 줄로 나뉘는 건가요? 일반이랑 똑같나요 ?..$()\ls\\\\lsls

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_VOLTDBsum이 $VOLTDB_LIB확장되며, 각 명령에 대해 하나의 파일보다 더 많은 값이 있을 수 있습니다 ls. *저기 보이 나요? 이는 왼쪽(voltdb-)과 오른쪽(.jar) 사이의 모든 항목으로 확장되는 와일드카드입니다.

이는 다음과 일치합니다.

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

노트:to -the Past 명령은 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에서 입력을 받아 각 인수를 공백으로 구분한 다음 인쇄합니다 :. ' 가 여러 개 주어지면 한 번에 2개의 인수를 허용하라는 -의미입니다. paste시간, 한 번에 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 ':' - )

\lsif 와 유사합니다 ls. 단, if ls는 별칭이고 백슬래시는 별칭 확장을 방지합니다. 이렇게 하면 ls분류자 접미사( )와 같이 원치 않는 출력을 추가할 수 있는 별칭을 사용하는 대신 명령이 사용됩니다 -F.

이러한 ls명령은 기존 파일 이름을 인수로 사용하여 호출되며 해당 인수를 한 줄에 하나씩 나열합니다. -1출력이 ls터미널 대신 파이프로 전송되므로 이 옵션은 효과가 없습니다. 수신된 인수가 기존 파일의 이름이 아닌 경우 ls표준 출력에는 오류만 인쇄합니다. 명령의 오류는 ls어디로든 리디렉션됩니다 2> /dev/null. 파일이 아닌 인수를 받을 수 있는 이유는 두 가지입니다 ls. 변수 중 하나가 읽을 수 있는 기존 디렉터리를 참조하지 않거나 와일드카드 패턴과 일치하는 파일이 없는 경우입니다. 두 경우 모두 스키마는 확장되지 않은 상태로 ls.

줄 끝의 백슬래시로 인해 쉘은 다음 개행 문자를 무시합니다. 쉘은 사용되는 모든 지점에서 선택적 개행 문자를 기대하기 때문에 여기서는 그 어느 것도 유용하지 않습니다.

중괄호 { … } 그룹 명령. 복합 명령은 { \ls …; \ls …; \ls … ; }로 파이프 paste되고 해당 오류는 로 리디렉션됩니다 /dev/null.

paste명령은 모든 입력 행을 함께 연결합니다 :. 끝에 a를 추가 tr '\n' :하지 않는다는 점을 제외 하면 동일합니다 .:

명령 대체로 $(…)인한 출력은 변수 값 뒤에 paste삽입되며 두 부분을 콜론으로 구분합니다.APPCLASSPATHCLASSPATH

이것은 단순화된 버전입니다. 일치하는 와일드카드 패턴이 없으면 추가 후행 콜론이 없다는 점에서 원래 버전과 약간 다릅니다 APPCLASSPATH( CLASSPATH바람직할 수 있음).

APPCLASSPATH=$CLASSPATH:$(
  \ls "$VOLTDB_VOLTDB"/voltdb-*.jar "$VOLTDB_LIB"/*.jar "$VOLTDB_LIB"/extension/*.jar |
  tr '\n' :) 2>/dev/null
APPCLASSPATH=${APPCLASSPATH%:}

관련 정보