編寫對文件名列表進行操作的 bash 函式
我想
cpfromserver
在 bash 中定義函式,以便在執行時$ cpfromserver xxx yyy zzz
結果和我輸入的一樣
$ scp user@remote.server:"/some/location/xxx/xxx.txt /some/location/xxx/xxx.pdf /some/location/yyy/yyy.txt /some/location/yyy/yyy.pdf /some/location/zzz/zzz.txt /some/location/zzz/zzz.pdf" /somewhere/else/
它適用於任意數量的參數。
(也就是說,對於我指定為函式的每個參數,函式應該從目錄複製
filename.txt
並filename.pdf
從本地目錄複製/some/location/filename/
到remote.server
本地目錄。並在一個連接中完成所有操作。)/somewhere/else/``filename``ssh
目前,我編寫了一個適用於單個參數的函式,我只是循環它,但這會
ssh
為每個參數建立單獨的連接,這是不可取的。我的困難在於,我只知道如何通過函式參數的位置( 、 等)單獨使用函式參數
$1
,$2
而不知道如何操作整個列表。$$ Note that I am writing this function as a convenience tool for my own use only, and so I would prioritize my own ease of understanding over handling pathological cases like filenames with quotation marks or linebreaks in them and whatnot. I know that the filenames I will be using this with are well-behaved. $$
試試這個方法:
cpfromserver () { files='' for x in "$@" do files="$files /some/location/$x/$x.txt /some/location/$x/$x.pdf" done scp user@remote.server:"$files" /somewhere/else/ }
評論中的重要警告:“值得注意的是,這種解決方案絕對不適用於復雜的文件名。如果文件名包含空格、換行符或引號,這種方法肯定會失敗。”
這裡有一個簡單的例子:
#!/bin/bash files_to_copy='' destination_directory='' while (("$#")) ; do if [[ "$@" = "$1" ]] ; then # last argument destination_directory="$1" else # argument files_to_copy="$files_to_copy $1" fi shift done scp user@remote.server:"$files_to_copy" $destination_directory;
如果你跑步
./example.sh foo.pdf foo.txt foo.jpg backup/
,你應該得到:# this will be executed scp user@remote.server:" foo.pdf foo.txt foo.jpg" backup/