systemctl\ {restart,status}\ sshd\;가 작동하지 않는 이유는 무엇입니까?

systemctl\ {restart,status}\ sshd\;가 작동하지 않는 이유는 무엇입니까?

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. 내가 여기서 뭘 잘못하고 있는 걸까? 왜 작동하지 않나요?

답변1

그것은 형태이다지원 확장쉘에서 완료되었습니다. 버팀대 확장이라는 개념은 맞지만 여기서 사용되는 방식은 올바르지 않습니다. 이 작업을 수행할 때:

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

답변2

이것은 ... 불리운다버팀대 확장(라벨에 표시된 대로).

내가 여기서 뭘 잘못하고 있는 걸까? 왜 작동하지 않나요?

예를 들어 Bash에서 명령줄을 읽고 실행하는 단계를 고려해보세요.

  1. 한 줄을 읽어라
  2. 가능한 복합 명령을 구성 요소 단순 명령으로 구문 분석
  3. 간단한 명령에 대한 다양한 확장(중괄호 확장, 단어 분리기, 와일드카드 등)
  4. 그런 다음 간단한 명령이 실행됩니다(명확성을 위해 다른 단계는 생략됨).

당신이 하고 싶은 것은 (3)의 (2)에 영향을 미치는 것입니다. 분할은 ;복합 명령을 구문 분석하는 단계 (2)를 기반으로 합니다 . 중괄호 확장이 발생할 때(3)에는 복합 명령을 생성하기에는 이미 너무 늦었습니다.

답변3

첫번째 줄

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

토큰 3개로 확장

  • 에코
  • systemctl 재시작 sshd;
  • systemctl 상태 sshd;

그런 다음 마지막 두 마커를 에코 에코하면 좋아 보입니다.

같은 두 번째 줄

systemctl\ {restart,status}\ sshd\;

토큰 2개로 확장

  • systemctl 재시작 sshd;
  • systemctl 상태 sshd;

systemctl restart sshd;bash는 찾을 수 없는 실행 파일을 찾으려고 합니다 .

당신은 어두운 면에서 여행을 시작하고 eval systemctl\ {restart,status}\ sshd\;예상치 못한 일을 조심하고 싶을 수도 있습니다.

관련 정보