脚本中的文件名包含空格

脚本中的文件名包含空格

这是一个简单的脚本,用于传递文件路径ls,但chmod带有空格的文件名即使用引号括起来也不起作用。

我怎样才能让它工作?

#!/bin/sh
# Script to fix permissions on supplied folder and file name

echo "Enter Folder name"
read folder
echo "Folder name is "$folder
echo "Enter File name - if name includes spaces enclose in single quote marks"
read filename 

echo "File name is "$filename
fullpath="/home/abc/"$folder"/"$filename

echo "Full path is "$fullpath

fixcommand="chmod a+rw -v "$fullpath

echo "Command to be executed is "$fixcommand

echo -n "Is that correct (y/n)? "
read answer
if echo "$answer" | grep -iq "^y" ;then
$fixcommand
else
    echo No action taken
fi 

答案1

在您提供的脚本中,这些变量实际上没有被引用

您应该更新脚本并用“ ”引用变量

例如:

fullpath="/home/abc/"$folder"/"$filename

应该:

fullpath="/home/abc/$folder/$filename"

感谢@glenn jackman - 他建议阅读忘记在 bash/POSIX shell 中引用变量的安全隐患

您可以在下面找到完整的反馈shell-check 站点在你的脚本上

Line 5:
read folder
^-- SC2162: read without -r will mangle backslashes.

Line 6:
echo "Folder name is "$folder
                      ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 8:
read filename
^-- SC2162: read without -r will mangle backslashes.

Line 10:
echo "File name is "$filename
                    ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 11:
fullpath="/home/abc/"$folder"/"$filename
                     ^-- SC2027: The surrounding quotes actually unquote this. Remove or escape them.

Line 13:
echo "Full path is "$fullpath
                    ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 17:
echo "Command to be executed is "$fixcommand
                                 ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 19:
echo -n "Is that correct (y/n)? "
     ^-- SC2039: In POSIX sh, echo flags are undefined.

Line 20:
read answer
^-- SC2162: read without -r will mangle backslashes.

答案2

引号对 来说没有任何意义read,并且会显示在变量中。变量内的引号也只是普通字符:在 shell 处理中,没有任何步骤可以让引号在变量扩展后生效。

唯一的例外是如果你明确地添加了另一层 shell 处理,可以通过运行bash -c "$somevar"或使用 来eval添加。但这不是一个好主意,因为通常你会想要避免混合数据和代码。


因此,您需要做的是 1)将read用户的输入以尽可能少的更改传递给变量,然后 2)使用引号内的变量将其从 shell 传递给命令而不进行任何更改。

read filename单独使用时基本没问题,它可以处理字符串中间的空格。但它会删除开头和结尾的空格,并将反斜杠视为特殊字符。要关闭这些功能,请使用IFS= read -r filename

使用变量时,必须以 的形式运行命令 chmod a+rw -v "$filename"

您不能将整个内容保存到变量中,否则无法将其正确拆分回去。"$fixcommand"将把整个值视为单个字符串,即命令的名称。$fixcommand也会拆分您的文件名。(Bash常见问题 050讨论将命令保存到变量)


总而言之:

IFS= read -r filename 
fullpath="/home/abc/$folder/$filename"
echo "Command to be executed is: chmod a+rw -v \"$filename\""
# confirmation...
chmod a+rw -v "$filename"

答案3

感谢大家最终工作版本是:

#!/bin/sh
# Script to fix permissions on supplied folder and file name                  
# including folders and filenames containing spaces
echo "Fixfilepermissions running" 

echo "Enter Folder name"
IFS= read -r folder
echo "Folder name is "$folder
echo "Enter File name"
IFS= read -r filename 
echo "File name is "$filename

fullpath="/home/abc/$folder/$filename"

echo "Full path is "$fullpath

echo "Command to be executed is: chmod a+rw -v \"$fullpath\""
echo -n "Is that correct (y/n)? "
read answer
if echo "$answer" | grep -iq "^y" ;then
chmod a+rw -v "$fullpath"
else
    echo "No action taken"
fi

相关内容