Bash 如何在管道中循环输入到封装的命令;“做”;

Bash 如何在管道中循环输入到封装的命令;“做”;,bash,curl,while-loop,pipe,stderr,Bash,Curl,While Loop,Pipe,Stderr,我打算在下载文件时获取(然后修改)cURL输出 curl -# -L --user-agent 'Mozilla/5.0' -o "`echo -e "$filename"`" "$url" 2>&1 | while true do read <&1 line1 line2 echo $line2 if [ "`echo $line2 | grep -o "#"`" = "#" ] ; t

我打算在下载文件时获取(然后修改)cURL输出

    curl -# -L --user-agent 'Mozilla/5.0' -o "`echo -e "$filename"`" "$url" 2>&1 |
    while true
    do
        read <&1 line1 line2
        echo $line2
            if [ "`echo $line2 | grep -o "#"`" = "#" ] ; then
                echo "downloading..."
                break
            elif [ "`echo $line2 | grep -o "curl"`" = "curl" ] ; then
                echo $line2
                break
            else
            echo "stderr still empty"    
            fi
    done
如果您想在curl下载时报告“正在下载…”,您可能希望执行以下操作(注意-有点高级的bash hacking):

你应该这么做

... -o "$filename" ...
当您只想让bash将
$filename
扩展为
-o
参数的值时,实际上没有理由使用额外的间接寻址

*)这毫无意义:

read <&1

出于许多原因,首先,
grep-o
几乎毫无用处,特别是对于简单的文本搜索,因为它只会输出您想要查找或不想要的内容(取决于是否找到了值),而该内容正好映射到
grep
退出代码为0或1。因此,如果echo$var | grep-q“value”;然后。如果
grep
成功,此表达式将成功,否则将失败
-q
用于使输出静音,因为您不需要它(只要它成功与否)。另外,如果您在变量中包含文本,那么使用
echo
将其发送到
grep
是很烦人的(它会打开一个子外壳,并分叉和填充),而是说
grep-q“value”…但是
read
应该等待缓冲区填充。我可以在读取
循环时将curl输出直接传输到
,没有问题。也许你可以发布你的错误?(因为将curl的进度条变灰并不是最好的主意…)我想做的是,首先检查下载是否正确开始,或者curl是否返回错误,然后(为了简化)将进度条打印为绿色或红色。我刚刚意识到:在日志的每一行末尾都有一个^M(CTRL-M)我设法用
sed$'s/\r/\\\n/g'
tr'\r'\n'log2
转换了它们,谢谢@Guss,这是一个非常有启发性的答案!您的最后一部分代码可以完成这个任务,是的,但我不喜欢
睡眠1
,因为如果internet连接有点慢,这个结构可能无法正常工作。。。这就是为什么我打算抓住输出。我不知道为什么,但当我将curl输出管道化到tr或sed时,输出总是空的!你对此有什么想法吗?我忘了提到你的代码无法工作的主要原因-curl进度通知是在标准错误流(文件描述符2)上发送的,因此连接到标准输出的管道将看不到进度消息。是的,没错,但是我的curl命令在1上复制了fd2!请看我更新的答案-我想它有你需要的一切。我将需要一段时间来处理和测试所有这些,但它似乎很好,非常感谢Guss:)我正想使用-v和-s选项来获取输出并从中进行测试。但是为什么我不能在进度条打开时正确地传输输出呢?这仍然是个谜。。。
... -o "`echo $filename`" ...
... -o "$filename" ...
read <&1
if [ "`echo $var | grep -o "value"`" == "value" ]; then