【问题标题】:Bash script wildcard not working with existing fileBash脚本通配符不适用于现有文件
【发布时间】:2018-04-20 04:35:36
【问题描述】:

我有一个脚本,它将带有通配符的 hdfs 文件路径分配给变量,但通配符不知何故不起作用。所以我写了这个测试脚本,在我的主目录中创建了一个文件some-file.txt

FILEPATH=~/some*
echo $(ls $FILEPATH)
echo $FILEPATH

APPJAR=hdfs:///user/myusername/myproject/lib/myproject*.jar
echo $(hdfs dfs -ls $APPJAR)
echo $APPJAR

而且输出让我感到惊讶,因为前 3 行产生了我预期的结果,但 hdfs 行没有。

/home/myusername/some-file.txt
/home/myusername/some-file.txt
-rw-r--r-- 3 myusername supergroup 188267249 2018-04-19 23:20 hdfs:///user/myusername/myproject/lib/myproject-1.0.1-SNAPSHOT-f7b.jar
hdfs:///user/myusername/myproject/lib/myproject*.jar

显然,自从hdfs dfs -ls 命令起作用后,该文件就存在于 HDFS 中。但是为什么APPJAR 变量没有成为实际的文件名呢?是不是 hdfs 命令的问题?

【问题讨论】:

    标签: bash hdfs wildcard


    【解决方案1】:

    这里的关键是 shell 无法识别 hdfs:// URL;在那种情况下,我很确定扩展是由 hdfs 命令完成的(或者 not 完成,如果没有 hdfs 命令)。当 shell 看到hdfs:///user/myusername/myproject/lib/myproject*.jar 时,它会查找一个名为“hdfs:”的目录(在当前工作目录下)(是的,“:”是一个合法的文件名),以及该目录下的一个“user”子目录等。找不到它们,它使通配符未展开。

    我有几个一般性建议:

    • 不要使用echo $(somecommand),直接运行命令即可。使用$( ) 捕获命令的输出,然后使用echo 将其转换回输出只会增加额外的混乱层。

    • 在执行命令之前使用set -x 使shell 打印命令,这样您就可以看到在哪里发生了哪些扩展。例如,您会看到,当您分配 FILEPATH=~/some* 时,~ 会扩展为您的主目录路径分配完成之前,但 * 直到稍后。

    • 如果您不想将变量引用拆分为单词并扩展嵌入的通配符,请在变量引用周围加上双引号。 echo "$variable" 将打印$variable 的内容,而echo $variable 将在打印之前扩展通配符。

    • 不要使用全大写的变量名;请改用小写或混合大小写。有大量具有特殊含义的全大写变量,如果您尝试将其中一个用于其他用途(例如PATH),您将会遇到问题。

    【讨论】:

    • 对于像我这样的新手 bash 脚本编写者来说很重要。欣赏输入。接受并赞成。
    【解决方案2】:

    简单的答案是 Bash 不会自动识别 HDFS 等任意协议。例如,您不会期望 https://example.org/*.txt 扩展。如果您安装 HDFS 文件系统驱动程序并挂载该目录,它将正常完成。

    【讨论】:

    • 是的,有道理...所以基本上,我想要实现的事情必须通过解析hdfs dfs -ls的输出来完成,对吗?
    猜你喜欢
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 2018-10-09
    • 2015-05-04
    • 2014-04-01
    • 2012-10-14
    • 1970-01-01
    • 2012-02-16
    相关资源
    最近更新 更多