여러 줄의 변수가 포함된 명령 출력을 터미널에 직접 저장하면 다음과 같은 결과가 나타납니다.
$ dirs=$(ls -1d /mnt/*/)
$ echo $dirs
/mnt/ext4/ /mnt/local/ /mnt/remote/ /mnt/test/
$ echo "$dirs"
/mnt/ext4/
/mnt/local/
/mnt/remote/
/mnt/test/
그러나 posix 쉘 스크립트에서 이를 사용하면 결과가 다릅니다. 이게 스크립트야
#!/bin/sh
dirs=$(ls -1d $1)
echo "inline"
echo $dirs
echo "multiline"
echo "$dirs"
이것은 스크립트 출력입니다
$ ./test.sh /mnt/*/
inline
/mnt/ext4/
multiline
/mnt/ext4/
sh 대신 bash를 사용해도 이런 현상이 발생합니다.
전체 출력을 유지하기 위해 출력을 ls -1d /mnt/*/
변수에 저장하는 방법을 아는 사람이 있습니까?
for 루프 내에서 4개의 디렉터리 경로를 각각 구문 분석하고 싶습니다.
답변1
$ ./test.sh /mnt/*/
여기서 glob은 명령줄에서 수동으로 작성하는 것처럼 별도의 인수로 디렉터리 이름으로 확장됩니다.
$ ./test.sh /mnt/ext4/ /mnt/local/ /mnt/remote/ /mnt/test/
그러나 스크립트 자체 내에서는 첫 번째 매개변수만 인용하면 됩니다 $1
.
dirs=$(ls -1d $1)
모든 매개변수를 인용하려면 "$@"
(따옴표 포함)을 사용하세요.
그러나 디렉토리 이름을 사용하여 여기에서 수행하는 모든 작업은 해당 디렉토리에서 실행되며 ls
, 이는 단지 동일한 이름(비록 다른 행에 있음)을 인쇄할 뿐입니다. 따라서 인수 목록을 문자열로 원하는 경우 ls
명령을 전혀 실행할 필요가 없으며 할당만 하면 됩니다 dirs="$@"
.
그러나 전부는 아니지만 대부분의 경우 위치 인수에 파일 이름 목록을 유지하고 루프를 사용하여 반복하는 것이 더 좋습니다.
for f in "$@"; do ...
또는
for f
do ...
파일 이름에는 공백이 포함될 수 있으며 이름을 단일 문자열로 연결하면 이름에 있는 공백의 의미가 손실됩니다. foo bar doo
세 개의 파일일 수도 있고 두 개의 파일 foo bar
과 doo
.