我有一个名称包含空格的目录。我需要删除这个特定目录的内容。\
在删除内容之前,我正在转义目录名称中的空格。该rm
命令在终端上工作正常,但如果我在 Shell 脚本中使用它,它就不起作用。我明白了没有这样的文件或目录错误。
例如,我有以下目录结构,
Users/Neeraj/Documents/temp dir/dir with spaces/a.txt
我需要删除目录“dir with space”内的所有内容。我的 Shell 脚本中的代码如下所示
#!/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"/*
在这种情况下,反斜杠和引号都应该由 shell 处理,以防止它分割目录名。当您同时使用两者时,shell 会保留两个空格和引号内的反斜杠,因此rm
实际上进入了.../temp\ dir/dir\ with\ spaces/...
它应该得到的参数.../temp dir/dir with spaces/...
。
当您复制打印的命令时,shell 会看到反斜杠而不需要额外的引号,因此它会保留受反斜杠保护的空格并删除反斜杠,因此rm
会.../temp dir/dir with spaces/...
进入参数。