명령 대체에 대해 혼란스러워요. 나는 프로그래밍 언어 매크로와 같은 명령 대체를 생각합니다. 하위 쉘이 먼저 실행되고 상위 명령이 평가되기 전에 $(...)
표준 출력이 대체됩니다 . 하지만 이것이 전부 진실일까요?
다음 명령을 실행하려고 하면
echo {0..9} | xargs -n 2 $(echo 'echo | tac')
다음 출력을 보고 싶습니다.
8 9
6 7
4 5
2 3
0 1
하지만 대신 이걸 사세요
| tac 0 1
| tac 2 3
| tac 4 5
| tac 6 7
| tac 8 9
그렇다면 | tac
명령줄의 일부가 아닌 echo에 대한 인수로 캡처되는 원인은 무엇입니까? 정확한 메커니즘과 순서는 무엇이며 명령줄과 명령 대체는 어떻게 구문 분석, 범위 지정 및 평가됩니까? Linux 메타 프로그래밍 방식으로 명령줄을 동적으로 구축할 수 있습니까?
편집하다
을 사용할 수 있다는 것을 알고 있습니다 echo {0..9}| xargs -n 2 | tac
. 질문은 이론적입니다. 서브셸 예제가 동일한 결과를 생성하지 않는 이유에 관심이 있습니다.
답변1
보고 있는 문제의 근본 원인은 명령줄의 토큰화가 발생하는 방식 때문입니다. 이 특별한 경우, $(echo 'echo | tac')
확장하기 오래 전에 쉘은 사용자가 하나의 명령( echo {…}
)을 실행하고 |
해당 출력을 다른 명령( xargs -n 2 $(…)
)으로 파이프할 의도를 이미 알고 있습니다.
그런 다음 다음 단계에서는 패딩 $(…)
및 중괄호 확장을 {…}
통해 실제 명령이 실행됩니다. 이 단계에서 파이프 캐릭터를 생산한다면 뭐, 너무 늦어서 버스를 놓친 게 분명합니다.
이제 특수 메타 문자로 처리되지 않지만 xargs
일반(=>메타 문자가 아닌) 문자로 명령줄에 포함됩니다.
다시 시도하려면 다음을 수행해야 합니다 eval
.
eval "echo {0..9} | xargs -n 2 $(echo 'echo | tac')"
그러면 예상한 대로 출력됩니다.
답변2
Rome이 말하는 것 외에도 명령은 다음과 같아야 합니다.
echo {0..9}| xargs -n 2 | tac
이것은 생산할 것입니다
8 9
6 7
4 5
2 3
0 1
의미 없는 $(echo 'echo')를 사용하면 오류가 발생합니다.
추신. 긴 답변의 경우 |
출력을 한 명령에서 다음 명령으로 리디렉션하여 다음을 echo {0..9}
생성합니다.
0 1 2 3 4 5 6 7 8 9
xargs -n 2
이 입력을 받아들이고 생성합니다.
0 1
2 3
4 5
6 7
8 9
마지막으로 tac
해당 입력을 받아 반대 표현식을 생성합니다.
8 9
6 7
4 5
2 3
0 1
이것이 조금 더 명확해지기를 바랍니다.
편집하다:
echo {0..9} | xargs -n 2 $(echo 'echo | tac')
+ echo 0 1 2 3 4 5 6 7 8 9
++ echo 'echo | tac'
+ xargs -n 2 echo '|' tac
| tac 0 1
| tac 2 3
| tac 4 5
| tac 6 7
| tac 8 9
이것은 초기 구문을 사용하여 bash에 보내는 명령입니다. 무슨 일이 일어나고 있는지 명확하고 마지막으로 보냅니다.xargs -n 2 echo '|' tac
답변3
중복될 위험이 있지만(그러나 다른 사람이 명시적으로 말한 곳은 없습니다), 귀하의 이유는 다음과 같습니다.
echo {0..9} | xargs -n 2 $(echo 'echo | tac')
명령이 수행하는 작업은 다음과 동일하다는 것입니다.
echo {0..9} | xargs -n 2 'echo' '|' 'tac'
비교하다
echo {0..9} | xargs -n 2 echo foo bar
$(echo …)
이는 명령줄의 전체 구조( )를 구문 분석한 후 평가가 수행되므로 출력에서는 명령에 인수만 추가할 수 있기 때문에 발생합니다 . 원하는 것을 원하는 방식으로 하려면 이렇게 말해야 합니다.echo (something) | xargs (args)
$(echo …)
xargs
에코 {0..9} |평가하다xargs -n 2 $(echo 'echo | tac')
위험할 수 있으니 주의하세요 eval
. 이 콘텐츠에 대한 경고를 이 사이트에서 검색하고 주의를 기울이세요.