我是bash的新手,所以它一定是一件小事(我希望),但找不到问题的来源。
我有一个mysql数据库表名为"url"全是url。我想要的是把所有的名单和wget一起去拜访他们。仅此而已。
我有这个命令,直接在bash中启动可以工作:
while read dbname; do dbarray+=("$dbname"); done < <(mysql -u MYUSER -pMYPASSWD, -e 'select url from mydb.url where borrado="n" and status=200 and id_idioma = 1 order by id_url asc' -B -N -s --skip-column-names) && for dbname in `echo ${dbarray[*]}`; do wget --no-check-certificate $dbname -O /dev/null > /dev/null 2>&1; done && unset dbarray
但是,如果我把它放入一个sh文件并执行它,就会抛出一个错误(请注意,第3行是命令):
line 3: Syntax error near unexpected token `<'
我试图避免<()管道方法为"traditional"管道,但同样的,它可以直接在bash中作为命令执行,而不是在。sh文件
中执行。mysql -u MYUSER -pMYPASSWD -e 'select url from mydb.url where borrado="n" and status=200 and id_idioma = 1 order by id_url asc' -B -N -s --skip-column-names | while read dbname; do dbarray+=("$dbname"); done && for dbname in `echo ${dbarray[*]}`; do wget --no-check-certificate $dbname -O /dev/null > /dev/null 2>&1; done && unset dbarray
在这种情况下没有抛出错误,但需要1秒的芬兰语和不做任何事情,不访问任何链接..
尝试执行./myfile.sh和sh myfile.sh,没有运气…
你能帮我从sh文件使其工作或让我了解问题在哪里吗?
请注意,它有3个命令与&&连接:1获取所有url并与它们创建一个变量,2循环变量和wget每次迭代,3删除变量。我认为这是正确的方法,但也许我错了。很明显,我必须等芬兰语1完成2,芬兰语2完成3,这是我想要的。在你看来,这是正确的近似吗?
欢呼在管道中,将在子shell中设置变量。换句话说:
echo foo | while read a; do var="$a"; done
echo "$var"
将打印空行,因为var
在子shell退出时消失。解决这个问题的一种方法是:
echo foo | {
while read a; do var="$a"; done
echo "$var"
}
或:
while read a; do var="$a"; done << EOF
$(echo foo)
EOF
echo "$var"
换句话说,您可以尝试:
mysql ...
| {
while read dbname; do dbarray+=("$dbname"); done
for dbname in "${dbarray[@]}"; do
wget ... "$dbname" ...
done;
}
不再需要取消设置dbarray
,因为它会在块的末尾自动消失。用"${dbarray[@]}"
比用$(echo ${dbarray[*]})
好你当然需要在wget
调用的"$dbname"
周围加上双引号。
注意这个数组似乎是不必要的。直接在while/read
循环中执行wget
,而不是给数组赋值。