내 'rm' 명령이 Mac 터미널에서는 제대로 실행되지만 쉘 스크립트에서는 실행되지 않는 이유는 무엇입니까?

내 'rm' 명령이 Mac 터미널에서는 제대로 실행되지만 쉘 스크립트에서는 실행되지 않는 이유는 무엇입니까?

이름에 공백이 포함된 디렉터리가 있습니다. 이 특정 디렉터리의 내용을 삭제해야 합니다. \내용을 삭제하기 전에 디렉터리 이름의 공백을 이스케이프 처리합니다. 이 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/...

관련 정보