Bash脚本将文件作为文件或目录返回

时间:2017-02-06 04:05:07

标签: bash

我正在尝试创建一个以文件作为输入的bash脚本。如果我在脚本中正常声明文件,那么脚本工作正常,但是当我尝试将其作为动态变量时,通过将文件放入脚本中它会中断。

e.g。

#!/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"落入终端返回:

  

不是文件

我不清楚为什么删除文件会将其从文件中更改为止。我尝试过很多变化都无济于事。

1 个答案:

答案 0 :(得分:1)

当您在图形环境中拖放fille时,shell可能在其提供的字符串中包含其他字符(例如引号)。您的脚本会尝试查找与shell提供的文件完全相同的文件(即包含引号),但找不到。

初步解决方案 - 不推荐,但留在这里是因为它适用于原始海报

你可以试试这个:

read input
printf -v input "$(eval echo "$input")"

printf语句执行两项操作:它使用-v inputinput变量分配新值。它指定的值是eval echo "$input"的输出,使用命令替换$()捕获。 eval强制在对它们作为命令执行它们之前传递的参数执行扩展。该命令最终为echo,其值为变量input的(扩展)初始值。

请记住:read不会执行扩展或单词拆分,只需将您键入的内容放入变量中即可。

请注意,使用eval会打开代码注入风险。特制的值可能会导致eval执行任意代码,而我提出的代码并不能保护代码。如果已知发送到终端窗口的字符串的确切格式,则有更安全,更好的方法。

更新 - 基于原始海报的其他详细信息的推荐

例如,如果您知道文件名在单引号内,则可以执行此操作(这也将忽略前导和尾随空格):

read input
if
  [[ $input =~ ^[[:space:]]*\'(.*)\'[[:space:]]*$ ]]
then
  input="${BASH_REMATCH[1]}"
fi

此代码段将从单引号内部提取文件名,如果它们在那里,或者将保留输入,否则从代码注入的角度来看更安全。