Bash
Bash globbing 和參數傳遞
我有以下簡化的 bash 腳本
#!/bin/bash files=("$@") if [ "X$files" = "X" ]; then files=$HOME/print/*.pdf; fi for file in "${files[@]}"; do ls "$file"; done
如果我將參數(文件名)作為參數傳遞,此腳本將列印正確的文件名。另一方面,如果我不傳遞參數,它將列印
/home/user/print/*.pdf: No such file or directory
為什麼在這種情況下文件名沒有擴展,我該如何解決?請注意,我使用
files=("$@")
and"${files[@]}"
結構是因為我讀到它比通常的“files=$*”更受歡迎。
您分配
files
為標量變數而不是數組變數。在
files=$HOME/print/*.pdf
您正在為標量(又名字元串)變數分配一些字元串。
/home/highsciguy/print/*.pdf``$files
採用:
files=(~/print/*.pdf)
或者
files=("$HOME"/print/*.pdf)
反而。shell 會將該 globbing 模式擴展為文件路徑列表,並將它們中的每一個分配給
$files
array的元素。glob 的擴展是在賦值時完成的。
您不必使用非標準的 sh 功能,您可以通過編寫它來使用您的系統
sh
而不是bash
這裡:#!/bin/sh - [ "$#" -gt 0 ] || set -- ~/print/*.pdf for file do ls -d -- "$file" done
set
是分配"$@"
位置參數的數組。另一種方法可能是將通配模式儲存在標量變數中:
files=$HOME/print/*.pdf
$files
並在擴展變數時讓 shell 擴展 glob 。IFS= # disable word splitting for file in $files; do ...
在這裡,因為
$files
沒有引用(通常不應該這樣做),所以它的擴展受分詞(我們在此處禁用)和萬用字元/文件名生成的影響。因此
$HOME
包含萬用字元,它們也可以被擴展,這就是為什麼仍然最好使用數組變數。