[英]Bash script returns file as not a file or directory
我正在尝试制作一个bash脚本,将文件作为输入。 如果我在脚本中正常声明了文件,则脚本可以正常工作,但是当我尝试将其放置为脚本中的动态变量时,该文件会损坏。
例如
#!/bin/bash
input="$HOME/Desktop/test.txt"
if [ -f "$input" ]; then
echo "is file"
else
echo "is NOT file"
fi
返回:
是文件
在哪里
#!/bin/bash
read input
if [ -f "$input" ]; then
echo "is file"
else
echo "is NOT file"
fi
将文件“ $ HOME / Desktop / test.txt”放入终端后,返回:
不是档案
我不清楚为什么删除文件会将其更改为非文件。 我尝试了许多变种但无济于事。
在图形环境中拖放圆角时,外壳程序可能会在其提供的字符串中包含其他字符(例如引号)。 您的脚本试图找到与shell提供的文件完全相同的文件(即包含引号),但找不到该文件。
最初的解决方案-不推荐,但留在这里,因为它适用于原始海报
您可以尝试这样:
read input
printf -v input "$(eval echo "$input")"
该printf
语句有两件事:它使用-v input
为input
变量分配一个新值。 它分配的值是eval echo "$input"
的输出,用命令替换$()
捕获。 eval
强制在将其作为命令执行之前对传递的参数执行扩展。 该命令最终是echo
,其值为变量input
的(扩展)初始值。
切记:如果仅使用您键入的内容并按原样放入变量中,则read
不会执行扩展或单词拆分。
请注意,使用eval
增加代码注入的风险。 特制的值可能会导致eval
任意执行代码,而我提议的代码对此不提供保护。 如果知道发送到终端窗口的字符串的确切格式,则有更安全,更好的方法。
更新-根据原始海报的其他详细信息提出建议
例如,如果您知道文件名在单引号内,则可以执行此操作(这也会忽略前导和尾随空格):
read input
if
[[ $input =~ ^[[:space:]]*\'(.*)\'[[:space:]]*$ ]]
then
input="${BASH_REMATCH[1]}"
fi
此代码段将从单引号中提取文件名(如果存在的话),否则将保留输入内容,从代码注入的角度来看,这样做更安全。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.