我有一个脚本,它将带有通配符的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命令中的问题吗?
答案 0 :(得分:2)
这里的关键是shell无法识别hdfs:// URL;在这种情况下,我很确定扩展是由supplier = getattr(db, supplier_name + "_properties")
prop = pd.DataFrame(list(supplier.find()))
命令完成的(如果没有hdfs
命令,则不完成)。当shell看到hdfs
时,它会查找名为“hdfs:”的目录(在当前工作目录下)(是的,“:”是文件名中的合法内容)和“user”子目录在那之下,等等没有找到它们,它会使通配符无法扩展。
我有几个一般性的建议:
不要使用hdfs:///user/myusername/myproject/lib/myproject*.jar
,只需直接运行命令即可。使用echo $(somecommand)
捕获命令的输出,然后使用$( )
将其转回输出只会增加额外的混淆。
在执行shell命令之前使用echo
来创建shell打印命令,这样可以让您了解在哪里进行扩展。例如,当您分配set -x
时,您会看到FILEPATH=~/some*
在分配完成之前已扩展到主目录的路径,但是~
直到稍后才会扩展。
如果您不希望将它们拆分为单词并展开嵌入的通配符,请在变量引用周围加上双引号。 *
将打印echo "$variable"
的内容,而$variable
会在打印之前展开通配符。
不要使用全大写变量名;使用小写或混合大小写。有大量具有特殊含义的全大写变量,如果您尝试将其中一个用于其他内容(例如echo $variable
),那么您将遇到问题。
答案 1 :(得分:0)
简单的答案是Bash不能自动识别像HDFS这样的任意协议。例如,你不会期望https://example.org/*.txt
扩展。如果您安装HDFS文件系统驱动程序并安装目录,它将完成正常。