왜 systemctl \ {restart, status} \ sshd \; 작업? 나타납니다. # systemctl\ {restart,status}\ sshd\; bash: systemctl

echo를 통과 할 때 위 명령의 출력은 다음과 같습니다.

# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;

출력을 터미널에 붙여 넣더라도 명령이 작동합니다. 그러나 명령을 직접 실행하려고하면 다음과 같은 결과가 나타납니다.

# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...

두 가지 질문이 있습니다 ..

  1. 이 대체 및 확장 방법은 정확히 무엇입니까? (내가 연구하고 그것에 대해 더 잘 배울 수 있도록 올바르게 사용하는 방법).
  2. 내가 여기서 뭘 잘못 했니? 왜 작동하지 않습니까?


답변

쉘에서 수행되는 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에서 명령 행을 읽고 실행하는 단계를 고려하십시오 (예 :).

  1. 줄을 읽다
  2. 가능한 복합 명령을 구성 요소 단순 명령으로 구문 분석
  3. 간단한 명령에서 다양한 확장을 수행합니다 (괄호 확장, 단어 분리, 글 로빙 등).
  4. 그런 다음 간단한 명령을 실행합니다 (명확하게하기 위해 다른 단계는 생략 함).

당신이하려는 것은 (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\;예상치 못한 것을 조심하면서 어두운 곳으로 여행을 시작하십시오 .


답변