echo 이후 위 명령의 출력은 다음과 같습니다.
# echo systemctl\ {restart,status}\ sshd\;
systemctl restart sshd; systemctl status sshd;
출력을 터미널에 붙여넣어도 명령은 계속 작동합니다. 그러나 명령을 직접 실행하려고 하면 다음과 같은 결과가 나타납니다.
# systemctl\ {restart,status}\ sshd\;
bash: systemctl restart sshd;: command not found...
두 가지 질문이 있습니다.
- 이 대체 및 확장 방법을 정확히 무엇이라고 합니까? (그래서 나는 그것을 조사하고 그것에 대해 더 많이 배우고 올바르게 사용하는 방법을 배울 수 있습니다).
- 내가 여기서 뭘 잘못하고 있는 걸까? 왜 작동하지 않나요?
답변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에서 명령줄을 읽고 실행하는 단계를 고려해보세요.
- 한 줄을 읽어라
- 가능한 복합 명령을 구성 요소 단순 명령으로 구문 분석
- 간단한 명령에 대한 다양한 확장(중괄호 확장, 단어 분리기, 와일드카드 등)
- 그런 다음 간단한 명령이 실행됩니다(명확성을 위해 다른 단계는 생략됨).
당신이 하고 싶은 것은 (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\;
예상치 못한 일을 조심하고 싶을 수도 있습니다.