셸: GNU BASH
나는 한동안 다음 명령을 사용해 왔습니다.
echo "$(fmt -w 50 < foo.txt)" > foo.txt
문제 없습니다. 그러나 시도할 때:
fmt -w 50 < foo.txt > foo.txt
foo.txt 파일은 빈 파일이 됩니다. 이는 쉘에서 파싱하는 리디렉션 연산자가 서브쉘의 우선순위와 관련되어 있기 때문이라고 생각합니다.
GNU BASH 매뉴얼을 검색해도 결과가 나오지 않았습니다. 매뉴얼에 뭔가 빠졌는지 누군가 말해 줄 수 있나요? 저는 이 동작의 원인을 이해하여 이를 더욱 활용하고 문제를 일으킬 수 있는 모든 상황을 이해할 수 있기를 바랍니다.
답변1
Bash 매뉴얼에서,3.7.1 간단한 명령 확장:
간단한 명령을 실행할 때 셸은 왼쪽에서 오른쪽으로 다음과 같은 확장, 할당 및 리디렉션을 수행합니다.
명령 대체는 (2)에서 발생하는 확장 중 하나이며, (3)에서 확장 후에 리디렉션이 발생합니다. 이는 서브쉘과 아무 관련이 없으며 순전히 쉘이 작업을 수행하는 순서 때문입니다. (fmt -w 50 < foo.txt) > foo.txt
빈 파일도 생성됩니다.
답변2
사람들이 사용할 수sponge
공익사업:
fmt -w 50 < foo.txt | sponge foo.txt
원문에 대한 참고사항:
echo "$(fmt -w 50 < foo.txt)" > foo.txt
가장 먼저 실행되는 것은
fmt
출력이끈,즉큰따옴표로 묶인 내용입니다.fmt
완료될 때까지 다른 일은 일어나지 않습니다 .echo
문자열을 다음으로 인쇄합니다.표준 출력.그 동안
echo
출력은>
다음으로 리디렉션됩니다.foo.txt.
2단계와 3단계는 거의 동시에 발생합니다.
원래 코드에는 실제로 문제가 있습니다. 명령줄에는길이 제한. 당신이 입력하면foo.txt매우 크며, 특히 길이가 보다 큰 경우 getconf ARG_MAX
명령 echo
이 실패하거나 불완전한 결과를 제공합니다.