und*_*res 7 bash dash shell-script
是否有一种可靠的方法可以利用路径名扩展将文件名分配给变量?
这有效,但看起来有点狡猾:
the_file="$(echo ~/downloads/stack-*-linux-x86_64-static.tar.gz)"
Run Code Online (Sandbox Code Playgroud)
如果文件存在,则将其完整路径分配给$the_file,否则会出现虚假的 glob 模式。
Globbing 仅发生在列表上下文中,因此您需要分配给数组变量。随着ksh93,bash,zsh,mksh或yash:
the_files=(~/downloads/stack-*-linux-x86_64-static.tar.gz)
Run Code Online (Sandbox Code Playgroud)
或在sh:
set -- ~/downloads/stack-*-linux-x86_64-static.tar.gz
Run Code Online (Sandbox Code Playgroud)
分配到$1,$2...
并获得第一个元素:"${the_files[1]}"in zshor yash(或只是$the_files[1]in zsh)或"${the_files[0]}"in kshor bash。
对于所有元素:("${the_files[@]}"也在$the_files中zsh)。
用于连接与$IFS: "${the_files[*]}"(也"$the_files"与zsh)的第一个字符连接的元素。或与任何字符串中加入zsh:${(j:, :)the_files}(这里加入,)。
the_file=~/downloads/stack-*-linux-x86_64-static.tar.gz
Run Code Online (Sandbox Code Playgroud)
该~会扩大,但没有水珠。但是,如果您在扩展变量时忘记使用引号,例如:
printf '%s\n' $the_file # instead of printf '%s\n' "$the_file"
Run Code Online (Sandbox Code Playgroud)
然后内容$the_file将受到 split+glob 的影响并在那时扩展,这可能会让您认为它有效,而实际上它不起作用,并且在这里与波浪号扩展相结合,它甚至会变得更加混乱。
例如,如果您的$HOMEis/All * Users/me和$IFS设置为其默认值,$the_file则将包含/All * Users/me/downloads/stack-*-linux-x86_64-static.tar.gz并printf打印/All当前目录中的所有文件名( 的扩展*),然后是Users/me/downloads/stack-*-linux-x86_64-static.tar.gz.
在 中zsh,你会得到一个错误,但在其他 shell 中,模式保持不变。最好的方法是让模式完全扩展到无。
使用zsh,这是使用Nglob 限定符:
the_files=(~/downloads/stack-*-linux-x86_64-static.tar.gz(N))
Run Code Online (Sandbox Code Playgroud)
ksh93它的~(N)glob 运算符具有类似的功能:
the_files=(~/downloads/~(N)stack-*-linux-x86_64-static.tar.gz)
Run Code Online (Sandbox Code Playgroud)
对于其他外壳,您需要打开一些全局选项(shopt -s nullglobin bash,set -o nullglobin yash)。