scp bash 脚本的多个参数
scp multiple arguments of bash script
我正在尝试使用 scp
从远程服务器复制多个文件。
我可以成功地为单个参数做到这一点 script file_number
其中 script
是:
#!/bin/bash
echo Insert your username:
read user
scp $user@server:/path/run*.lz4 ./
lz4 -mdv --rm run*.lz4
我所有的文件都采用以下格式:runXXXXsubY.lz4
这样我可以复制所有具有 XXXX==file_number
的文件,但我想传递多个参数,并复制所有这些文件,例如script 1 2
复制带有 xxxx==1
和 XXXX==2
的所有文件。
我试过:
scp $user@server:/path/run"$@"*.lz4 ./
但是 $@
在没有附加 *.lz4
的情况下得到扩展
我感谢任何在正确方向上的帮助。
谢谢
你最好的选择 IMO 是一个简单的 for 循环:
for xxx; do
scp "$user@server:/path/run${xxx}.lz4" ./
done
如果您确实想要 运行 一个 scp
(避免多次密码提示不是这样做的动机;避免多次密码提示的方法是设置您的 ssh 密钥,这样就不会密码是必需的),你可以使用 xargs:
printf "$user@server:/path/run%s.lz4[=11=]" "$@" | xargs -0 -J % scp % ./
这不保证单次调用,并且 xargs
将 运行 多次调用 scp
如果传递了足够多的 args 参数字符串超过特定限制,但这可能应该足够了。
基本问题是,当 shell 扩展 $user@server:/path/run"$@"*.lz4
时,它不会为每个参数复制 $user:...
和 *.lz4
部分,它只是有点盲目地将参数列表(包括参数之间的分词符)添加到中间。因此,如果参数是 1
和 2
,它实际上扩展为:
scp $user@server:/path/run"1" "2"*.lz4 ./
...所以 $user@server:/path/run"1"
和 "2"*.lz4
是 scp
的单独参数,这没有用。您可以做的是根据参数创建一个数组,然后使用 that 作为 scp
的源列表。像这样:
sources=()
for runNum in "$@"; do
sources+=("$user@server:/path/run${runNum}*.lz4")
done
scp "${sources[@]}" ./
然后为 lz4
命令使用单独的循环:
for runNum in "$@"; do
lz4 -mdv --rm run${runNum}*.lz4
done
编辑:为避免必须多次进行身份验证,您可以打开主 SSH 连接并让所有 scp
传输搭载在该连接上。这是一个示例,主要基于 Felix Rabe 的回答 here:
# Create the array of source file patterns to fetch
sources=()
for runNum in "$@"; do
sources+=("$user@server:/path/run${runNum}*.lz4")
done
# Open master SSH connection:
# (This is the only time you have to enter the password)
sshSocket=~/"$user@server"
ssh -M -f -N -S "$sshSocket" "$user@server"
# Actually copy the files:
scp -o ControlPath="$sshSocket" "${sources[@]}" ./
# Close master connection:
ssh -S "$sshSocket" -O exit "$user@server"
为远程文件名构建模式的一个参数替换想法:
$ fn="$@"
$ echo scp "user@server:/path/run{${fn// /,}}*.lz4" ./
假设 $@
= 222 333
这会生成:
scp user@server:/path/run{222,333}*.lz4 ./
注意: 一旦对格式感到满意,删除 echo
我正在尝试使用 scp
从远程服务器复制多个文件。
我可以成功地为单个参数做到这一点 script file_number
其中 script
是:
#!/bin/bash
echo Insert your username:
read user
scp $user@server:/path/run*.lz4 ./
lz4 -mdv --rm run*.lz4
我所有的文件都采用以下格式:runXXXXsubY.lz4
这样我可以复制所有具有 XXXX==file_number
的文件,但我想传递多个参数,并复制所有这些文件,例如script 1 2
复制带有 xxxx==1
和 XXXX==2
的所有文件。
我试过:
scp $user@server:/path/run"$@"*.lz4 ./
但是 $@
在没有附加 *.lz4
我感谢任何在正确方向上的帮助。
谢谢
你最好的选择 IMO 是一个简单的 for 循环:
for xxx; do
scp "$user@server:/path/run${xxx}.lz4" ./
done
如果您确实想要 运行 一个 scp
(避免多次密码提示不是这样做的动机;避免多次密码提示的方法是设置您的 ssh 密钥,这样就不会密码是必需的),你可以使用 xargs:
printf "$user@server:/path/run%s.lz4[=11=]" "$@" | xargs -0 -J % scp % ./
这不保证单次调用,并且 xargs
将 运行 多次调用 scp
如果传递了足够多的 args 参数字符串超过特定限制,但这可能应该足够了。
基本问题是,当 shell 扩展 $user@server:/path/run"$@"*.lz4
时,它不会为每个参数复制 $user:...
和 *.lz4
部分,它只是有点盲目地将参数列表(包括参数之间的分词符)添加到中间。因此,如果参数是 1
和 2
,它实际上扩展为:
scp $user@server:/path/run"1" "2"*.lz4 ./
...所以 $user@server:/path/run"1"
和 "2"*.lz4
是 scp
的单独参数,这没有用。您可以做的是根据参数创建一个数组,然后使用 that 作为 scp
的源列表。像这样:
sources=()
for runNum in "$@"; do
sources+=("$user@server:/path/run${runNum}*.lz4")
done
scp "${sources[@]}" ./
然后为 lz4
命令使用单独的循环:
for runNum in "$@"; do
lz4 -mdv --rm run${runNum}*.lz4
done
编辑:为避免必须多次进行身份验证,您可以打开主 SSH 连接并让所有 scp
传输搭载在该连接上。这是一个示例,主要基于 Felix Rabe 的回答 here:
# Create the array of source file patterns to fetch
sources=()
for runNum in "$@"; do
sources+=("$user@server:/path/run${runNum}*.lz4")
done
# Open master SSH connection:
# (This is the only time you have to enter the password)
sshSocket=~/"$user@server"
ssh -M -f -N -S "$sshSocket" "$user@server"
# Actually copy the files:
scp -o ControlPath="$sshSocket" "${sources[@]}" ./
# Close master connection:
ssh -S "$sshSocket" -O exit "$user@server"
为远程文件名构建模式的一个参数替换想法:
$ fn="$@"
$ echo scp "user@server:/path/run{${fn// /,}}*.lz4" ./
假设 $@
= 222 333
这会生成:
scp user@server:/path/run{222,333}*.lz4 ./
注意: 一旦对格式感到满意,删除 echo