这是一个简单的脚本,用于传递文件路径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