{} 및 여러 `\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_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%:}

관련 정보