파일을 열거나 생성하고 그 안에 루프로 많은 줄을 쓰고 싶습니다.
기본적으로 나는 이렇게 할 것이다:
for i in {1..100}; do
echo "line $i">>test.log
done
내 이해는 OS가 test.log
파일 i
시간을 열거나 닫는다는 것입니다.
나는 또 다른 구문/접근 방식을 발견했습니다.
exec {log}>>test.log
for i in {1..1000}; do
echo "line $i" >& $log
done
{log}>&-
이미 열린 파일을 사용하는
exec {log}>>test.log
동안 파일을 열거나 생성하고 열린 상태로 유지할 것이라고 가정합니까 ? 파일 핸들이 닫히나요?echo "line $i" >& $log
{log}>&-
이 방법을 무엇이라고 하나요? 사용 사례에 대한 자세한 정보는 어디서 찾을 수 있나요?
답변1
표시된 사용 사례에서는 for
복합 명령의 표준 출력을 리디렉션할 수 있습니다. 이렇게 하면 파일 설명자를 처리할 필요가 없습니다.
for i in {1..100}; do
printf 'line %d\n' "$i"
done >test.log
그러면 이름이 지정된 파일이 생성되거나 잘리고 test.log
루프 내 표준 출력 스트림의 모든 출력(다른 곳에서 명시적으로 리디렉션되지 않는 한)은 해당 파일로 이동됩니다. >>
파일을 자르는 대신 파일에 추가하는 데 사용됩니다 . 파일은 한 번만 열립니다.
다른 복합 명령으로도 동일한 작업을 수행할 수 있습니다.
if [ -e file ]; then
echo 'file exists'
else
echo 'file does not exist'
fi >out.log
{
echo 'line 1'
cat some-file
echo 'last line'
} >lines.txt
답변2
첫째, fd는 단일 루프 내에서만 사용되므로 나중에 수동으로 닫을 필요 없이 루프에 리디렉션을 적용하는 것도 가능합니다.
for i in {1..100}; do
echo "line $i"
done >>test.log
여기에서 루프 시작 부분에서 파일을 지우려면 > test.log
추가 리디렉션을 사용하는 대신 자르기 리디렉션을 사용할 수도 있습니다. >>
전체 루프에 대해 동일한 파일 핸들이기 때문에 루프 반복 간에 잘리지 않습니다.
exec
리디렉션을 처리하는 데 사용할 특정 이름이 있는지 잘 모르겠습니다 . 이는 전체 셸에 적용되는 리디렉션을 수정하는 방법일 뿐입니다. 조금 이상한 점은 의 또 다른 사용법이 exec
전체 셸을 대체하는 명령과 함께 사용된다는 것입니다. 그러나 여기서는 셸이 계속 실행됩니다.
하나는 {var}>filename
비표준 확장입니다.Bash 매뉴얼에 설명되어 있음:
각 리디렉션 앞에는 파일 설명자가 올 수 있지만 다음 형식의 단어가 앞에 올 수도 있습니다.변수 이름}. 이 경우 >&- 및 <&-를 제외한 모든 리디렉션 연산자에 대해 쉘은 10보다 큰 파일 설명자를 할당하고 이를 {변수 이름}. >&- 또는 <&- 앞에 {가 있는 경우변수 이름}, varname 값은 닫힐 파일 설명자를 정의합니다. 만약에 {변수 이름제공되면 리디렉션이 명령 범위를 벗어나 지속되므로 셸 프로그래머가 파일 설명자의 수명을 수동으로 관리할 수 있습니다.
또한 최소한 ksh 및 zsh에서 지원됩니다(Bash를 위해 그 중 하나에서 빌릴 수 있음).
자동 할당은 필요하지 않지만 고정된 금액을 사용할 수 있습니다. 예를 들면 다음과 같습니다.
exec 9>>test.log
for i in {1..100}; do
echo "line $i" >&9
done
exec 9>&-
fd 번호를 직접 추적하면 됩니다. 3부터 9까지의 숫자는 스크립트 작성자가 자유롭게 사용할 수 있어야 합니다. 0, 1, 2는 표준 파일 설명자이고 10 이상은 셸에서 내부적으로 사용할 수 있습니다.