이름에 공백이 포함된 디렉터리가 있습니다. 이 특정 디렉터리의 내용을 삭제해야 합니다. \
내용을 삭제하기 전에 디렉터리 이름의 공백을 이스케이프 처리합니다. 이 rm
명령은 터미널에서는 제대로 작동하지만 쉘 스크립트에서 사용하면 작동하지 않습니다. 알겠어요해당 파일이나 디렉터리가 없습니다.실수.
예를 들어, 다음과 같은 디렉터리 구조가 있고
Users/Neeraj/Documents/temp dir/dir with spaces/a.txt
"dir with space" 디렉터리 내의 모든 항목을 삭제해야 합니다. 내 쉘 스크립트의 코드는 다음과 같습니다
#!/bin/sh
TEMP_DIR="$HOME/Documents/temp dir/dir with spaces"
TEMP_DIR=$(echo $TEMP_DIR | sed 's/ /\\ /g')
COMMAND="rm -r $TEMP_DIR/*"
echo "Command: $COMMAND"
rm -r "$TEMP_DIR"/*
이 스크립트를 실행하면 다음과 같은 결과가 나타납니다.해당 파일이나 디렉터리가 없습니다.오류가 발생했지만 복사하고 터미널에서 동일한 명령을 실행하면 정상적으로 작동합니다.
산출:
Command: rm -r /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/*
rm: /Users/Neeraj/Documents/temp\ dir/dir\ with\ spaces/*: No such file or directory
이를 수행하는 올바른 방법은 무엇입니까?
노트: 저는 macOS를 사용하고 있습니다
답변1
@Olorins 답변이 이 질문에 대한 정답이지만 더 많은 정보를 추가하고 싶습니다.왜이것은 작동하지 않습니다:
다음 방법 중 하나를 사용할 수 있습니다.
rm "dir with spaces"
rm dir\ with\ spaces
dir="dir with spaces"; rm "$dir"
하지만 이것들은 작동하지 않습니다:
dir="dir\ with\ spaces";
rm "$dir" # the backslash will be taken literally inside quotes
rm $dir # this should work, shouldn't it? Please read below.
후자의 옵션은 처음에는 나에게 직관적이지 않았습니다. 그러나 bash는 변수 내용을 확장하여 일부 참조를 추가합니다.실행 전.
set -x
다음을 사용하여 실제로 실행되는 내용을 확인할 수 있습니다 .
( var="a\ b"; set -x; echo $var; )
+ echo 'a\' b
a\ b
출력은 괜찮아 보이지만 공백은 \
작은따옴표로 둘러싸여 있기 때문에 여전히 이스케이프되지 않습니다.
답변2
두 개의 따옴표를 사용하고 있습니다.그리고백슬래시가 이스케이프됩니다. 참조를 사용하는 것만으로도 괜찮습니다.
이것으로 충분합니다:
TEMP_DIR="$HOME/Documents/temp dir/dir with spaces"
COMMAND="rm -r $TEMP_DIR/*"
echo "Command: $COMMAND"
rm -r "$TEMP_DIR"/*
이 경우 디렉터리 이름이 분할되는 것을 방지하기 위해 백슬래시와 따옴표를 모두 쉘에서 처리해야 합니다. 둘 다 사용하면 쉘은 두 공간을 모두 유지합니다.그리고따옴표 안에 백슬래시가 있으므로 rm
실제로 .../temp\ dir/dir\ with\ spaces/...
는 .../temp dir/dir with spaces/...
.
인쇄된 명령을 복사하면 쉘은 추가 따옴표 없이 백슬래시를 확인하므로 백슬래시로 보호된 공백을 유지하고 백슬래시를 제거하므로 인수에 rm
들어갑니다 ..../temp dir/dir with spaces/...