echo를 통과 할 때 위 명령의 출력은 다음과 같습니다.
# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;
출력을 터미널에 붙여 넣더라도 명령이 작동합니다. 그러나 명령을 직접 실행하려고하면 다음과 같은 결과가 나타납니다.
# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...
두 가지 질문이 있습니다 ..
- 이 대체 및 확장 방법은 정확히 무엇입니까? (내가 연구하고 그것에 대해 더 잘 배울 수 있도록 올바르게 사용하는 방법).
- 내가 여기서 뭘 잘못 했니? 왜 작동하지 않습니까?
답변
쉘에서 수행되는 Brace 확장 의 한 형태입니다 . 괄호 확장 아이디어는 옳지 만 여기서 사용 된 방식은 올바르지 않습니다. 해야 할 때 :
systemctl\ {restart,status}\ sshd\;
쉘은 해석 systemctl restart sshd;
은 하나의 긴 명령으로 하여 실행하려고 시도하며, 그런 식으로 실행할 바이너리를 찾을 수 없습니다. 이 단계에서 쉘은 인수로 완전한 명령을 빌드하기 전에 명령 행에서 항목을 토큰 화하려고 시도하지만 아직 발생하지 않았습니다.
알려진 확장 값의 eval
경우 안전하게 사용할 수 있지만 확장하려는 값을 확인하십시오.
eval systemctl\ {restart,status}\ sshd\;
그러나 for
하나의 라이너를 작성하거나 사용하는 대신 대신 대신 루프를 사용하고 싶습니다 eval
.
for action in restart status; do
systemctl "$action" sshd
done
답변
이를 괄호 확장 이라고 합니다 (태그가 나타내는대로).
내가 여기서 뭘 잘못 했니? 왜 작동하지 않습니까?
bash에서 명령 행을 읽고 실행하는 단계를 고려하십시오 (예 :).
- 줄을 읽다
- 가능한 복합 명령을 구성 요소 단순 명령으로 구문 분석
- 간단한 명령에서 다양한 확장을 수행합니다 (괄호 확장, 단어 분리, 글 로빙 등).
- 그런 다음 간단한 명령을 실행합니다 (명확하게하기 위해 다른 단계는 생략 함).
당신이하려는 것은 (3)의 (2)에 영향을 미칩니다. 기반 분할 ;
은 복합 명령을 구문 분석 할 때 2 단계입니다. 중괄호 확장에 시간 (3)이 발생하기 전에 복합 명령을 작성하고 작성하기에는 이미 늦었습니다.
답변
첫 줄
echo systemctl\ {restart,status}\ sshd\;
3 토큰으로 확장
- 에코
- systemctl restart sshd;
- 시스템 상태 sshd;
그런 다음 마지막 두 토큰을 에코합니다. 그러면 괜찮아 보입니다.
마찬가지로 두 번째 줄
systemctl\ {restart,status}\ sshd\;
2 개의 토큰으로 확장
- systemctl restart sshd;
- 시스템 상태 sshd;
bash systemctl restart sshd;
는 찾을 수없는 실행 파일 을 찾습니다.
eval systemctl\ {restart,status}\ sshd\;
예상치 못한 것을 조심하면서 어두운 곳으로 여행을 시작하십시오 .