我目前正在编写一个bash脚本,使用GoogleCL将视频文件加载到YouTube。
由于我在循环中上传内容(因为可能有多个视频文件),我想检查每个文件是否已成功上传,然后再上传下一个文件。
命令google youtube post --access unlisted --category Tech $f
(其中$ f代表文件)输出一个字符串,告诉我上传是否成功。
但我不知道如何将“返回字符串”重定向到变量中以检查成功。
这就是我所拥有的:
for f in ./*.ogv ./*.mov ./*.mp4
do
if [[ '*' != ${f:2:1} ]]
then
echo "Uploading video file $f"
# How to put the return value of the following command into a variable?
google youtube post --access unlisted --category Tech $f > /dev/null
# Now I assume that the output of the command above is available in the variable RETURNVALUE
if [[ $RETURNVALUE == *uploaded* ]]
then
echo "Upload successful."
else
echo "Upload failed."
fi
fi
done
有人能帮助我吗?
答案 0 :(得分:21)
我的猜测是你可以依赖google命令的错误代码(我假设如果上传失败就会返回错误,但你应该仔细检查一下)。
for f in ./*.ogv ./*.mov ./*.mp4; do
if [[ '*' != ${f:2:1} ]]; then
echo "Uploading video file $f"
if google youtube post --access unlisted --category Tech "$f" > /dev/null
then
echo "Upload successful."
else
echo "Upload failed."
fi
fi
done
一个常见的误解是,如果想要一个括号括起来的表达式来评估,如果总是接受一个命令并检查错误状态,那就不是这样;通常此命令是[
,它是test
的别名,用于计算表达式。 (是的,如果没有一个优化的快捷方式让它在bash中变得更快,我会感到惊讶,但从概念上讲它仍然是真的。)
捕获输出是通过反引号完成的,如此
result=`command argument a b c`
或使用$()
result=$(command argument a b c)
但在这种情况下使用错误代码可能更好。
修改:
你的函数中有一个有趣的东西......起初我没有注意到,但如果启用nullglob
shell选项可以避免这种情况(这会使./*.mov
扩展为空字符串,如果没有文件)。另外,如果您的文件名包含空格,则引用$f
或它会中断
shopt -s nullglob
for f in ./*.ogv ./*.mov ./*.mp4; do
echo "Uploading video file $f"
if google youtube post --access unlisted --category Tech "$f" > /dev/null
then
echo "Upload successful."
else
echo "Upload failed."
fi
done
HTH。
答案 1 :(得分:4)
我会称之为The command ... outputs a string
。 ' Return '是一个关键字,返回值是一个数字,其中0表示按惯例成功(0个错误),不同的值表示错误代码。
您可以通过以下方式获取输出:
result=$(google youtube post --access unlisted --category Tech $f)
但经常会看到劣质解决方案:
result=`cmd param1 param2`
低级,因为反叛很容易与撇号混淆(取决于字体)并且难以嵌套,所以不要使用它们。
来自'man bash':
简单命令的返回值 是退出状态,如果是,则为128 + n 命令由信号n终止。
和
返回[n]
使函数以指定的返回值退出 由n。如果省略n,则返回 状态是最后一个 在函数体中执行的命令。如果在外面使用 功能,但在执行期间 脚本由。 (资源) 命令,它导致shell停止执行该脚本 并返回n或退出状态 最后一个命令 在脚本中执行作为退出状态 脚本。如果在功能之外使用 而不是在执行期间 脚本by。,返回状态为false。任何命令 与RETURN陷阱相关联的是 执行前执行 在函数或脚本之后继续。
最后一个命令的返回值/退出代码是通过$?获得的。
您指的含义的关键字是命令替换。再次'man bash':
命令替换
命令替换允许输出命令来替换 命令名称。有两种形式:$(command) or `command`
Bash通过执行命令并用标准替换命令替换来执行扩展 输出命令,删除任何尾随换行符。嵌入式换行 不会被删除,但它们可能会被删除 在分词时删除。 命令替换$(cat文件)可以替换为 相当但更快的$(< file)。
When the old-style backquote form of substitution is used,
反斜杠保留了它的字面含义 除了后跟$,`, 要么 。没有反斜杠的第一个反引号终止了 命令替换。使用时 $(命令)表格, 括号之间的所有字符组成命令;没有 特别对待。
反引形式,逃避内心 带反斜杠的反引号。Command substitutions may be nested. To nest when using the
如果替换出现在双引号内,则单词拆分 和路径名扩展不是 对结果进行了表达。
答案 2 :(得分:2)
使用$()
variable=$(google youtube post --access unlisted --category Tech $f )
答案 3 :(得分:2)
如果你仍然在> /dev/null
之后获得输出,那么它就会出现在stderr上,所以标准的反引号或$()
将不起作用。
首先,查看返回码是否表示存在问题:检查$?成功与失败之后。
如果事实证明返回代码不够,您可以重定向输出:
RETURNVALUE=$(google youtube post --access unlisted --category Tech $f 2>&1 >/dev/null)
在将stdout重定向到空之前, 2>&1
将stderr置于stdout fd上。
答案 4 :(得分:0)
您可以使用反引号将其指定给变量:
CONTENT=`google youtube post --access unlisted --category Tech $f > /dev/null`
答案 5 :(得分:0)
访问youtube的示例
rm ~/temp/youtube_top_title1.txt rm ~/temp/youtube_top1.txt curl "http://www.youtube.com/"|\ grep -o 'watch[^"]*'|\ sort -n|\ uniq -c|\ awk '{if ($1!="1") print $2}'|\ while read i ; do\ page_youtube=`curl -s "http://www.youtube.com/${i}"`;\ echo `echo -e "$page_youtube" |awk '{if ($1 ~ "") start=1; if ($1 ~ "") start=0; if (start == 1) print $0 }'|grep -v ''` >> ~/temp/youtube_top_title1.txt url_current=$(echo -e "$page_youtube"|\ grep -o "url=[^,]*,"|\ sed 's/url=//g;s/,//g'|\ php -r '$f=fopen("php://stdin","r");while (FALSE!==($line=fgets($f))) echo urldecode($line);'|\ awk '{print $1}'|\ sed 's/;$//g'|\ sed 's/\\u.*//g'|\ tail -2|\ head -1) echo "$url_current" >> ~/temp/youtube_top1.txt done
答案 6 :(得分:0)
read
命令。当然,所有这些其他答案都显示了不做OP所要求的方法,但这确实搞砸了我们其他寻找OP问题的人。
免责声明:This is a duplicate answer
# I would usually do this on one line, but for readability...
series | of | commands \
| \
(
read string;
mystic_command --opt "$string" /path/to/file
) \
| \
handle_mystified_file
series | of | commands
是一系列非常复杂的管道命令。mystic_command
可以接受stdin作为文件,但不是选项arg 因此必须作为变量** read
接受stdin并将其放入变量$string
read
和mystic_command
放入“子shell”中,但会使其像连续管道一样流动,就好像2个命令位于单独的脚本文件中一样。** 总有另一种选择,在这种情况下,替代方案是丑陋且难以理解的:
mystic_command --opt "$(series | of | commands)" /path/to/file | handle_mystified_file