使用xargs和两个参数进行并行下载

问题描述 投票:2回答:2

这个问题是another one asked some time ago的后续行动。

我目前有这个脚本:

download_data(){
    wget --load-cookies ~/.urs_cookies --save-cookies ~/.urs_cookies --auth-no-challenge=on --keep-session-cookies --content-disposition $1
}

export -f download_data
DIR=$(dirname "$1")
<$1 xargs -d $'\n' -P 5 -n 1 -- bash -c 'for arg; do download_data $arg; done' _

换句话说,我有一个包含大量URL的文本文件,每行一个,我将每个URL提供给wget以下载数据。

我想要做的是向download_data()添加另一个参数,以便选择文件的下载位置。就像是:

download_data(){
    wget -P $1 --load-cookies ~/.urs_cookies --save-cookies ~/.urs_cookies --auth-no-challenge=on --keep-session-cookies --content-disposition $2
}

export -f download_data
DIR=$(dirname "$1")
<$1 xargs -d $'\n' -P 5 -n 1 -- bash -c 'for arg; do download_data $DIR $arg; done' _

从理论上讲,这会将文件保存在我的文本文件的位置。但它不起作用:传递给download_data()的第一个参数始终为空。

我非常喜欢bash和所有这些,所以它可能是一些简单的遗漏......

谢谢您的帮助!

linux bash shell wget xargs
2个回答
1
投票

export的意义在于使变量在子壳中可见。

你已经export -f你的功能;同样,export你的DIR变量也是如此。

但是,您不应该为您的私有变量使用大写。你打破了报价。所以,

download_data(){
    # add missing double quotes
    wget -P "$1" --load-cookies ~/.urs_cookies --save-cookies ~/.urs_cookies --auth-no-challenge=on --keep-session-cookies --content-disposition "$2"
}

export -f download_data
# lowercase variable name
dir=$(dirname "$1")
# ... and export it
export dir
# ... and fix quoting some more
<$1 xargs -d $'\n' -P 5 -n 1 -- bash -c 'for arg; do
    download_data "$dir" "$arg"; done' _

不过,您可能会对_命令行末尾的xargs感到好奇。不明确或优雅地,我们也可以使用它来走私价值。它将用于在单引号内的脚本中填充$0。然后,我们不需要将它放在一个命名变量中,或者export那个变量。

<$1 xargs -d $'\n' -P 5 -n 1 -- bash -c 'for arg; do
    download_data "$0" "$arg"; done' "$(dirname "$1")"

1
投票

如果你可以使用GNU Parallel而不是xargs:

download_data(){
  wget -P $1 --load-cookies ~/.urs_cookies --save-cookies ~/.urs_cookies --auth-no-challenge=on --keep-session-cookies --content-disposition $2
}
export -f download_data
DIR=$(dirname "$1")
parallel -a $1 -P5 download_data $DIR {}
© www.soinside.com 2019 - 2024. All rights reserved.