Bash脚本,当我不希望它回显时

Aut*_*pps 1 bash curl

我有一个bash脚本,其中包装了一对curls,并通过其他一些内置函数进行管道传输。我想打印每个curl的结果,然后解析结果并发出包含其他信息的第三行。最终输出应如下所示:

https://e.thingzz.com/eqvjzc23xqo2s
https://e.thingzz.com/o7jlafrot2fok
https://e.thingzz.com/c/eqvjzc23xqo2s/o7jlafrot2fok
Run Code Online (Sandbox Code Playgroud)

相反,它看起来像:

https://e.thingzz.com/eqvjzc23xqo2s
https://e.thingzz.com/o7jlafrot2fok
/o7jlafrot2fokv.com/c/eqvjzc23xqo2s
Run Code Online (Sandbox Code Playgroud)

由于某种原因,它以前两行的确切长度进行换行。

脚本:

#!/usr/bin/env bash
function myCurl()
{
    curl ... | ... | ... 
    #omitted, results in printing a url like 'https://e.thingzz.com/UUID' 
}

# param validation omitted
URL1=$(myCurl "${1}")
URL2=$(myCurl "${2}")
# print both URLs
echo $URL1
echo $URL2

# Parse URLs to get ID at end
# I've also tried using `cut`, in case there were invisible characters?
# I don't really know what I'm talking about.
URLID1=$(echo $URL1 | awk -F 'https://thing.com/' '{print $2}')
URLID2=$(echo $URL2 | awk -F 'https://thing.com/' '{print $2}')

# Doesn't work. Looks like:
# /o7jlafrot2fokv.com/c/eqvjzc23xqo2s
echo https://thing.com/c/${URLID1}/${URLID2}
# Proves I can echo something longer
echo doneaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# Also wraps, exactly like the `echo` version
echo $URLID1 $URLID2 | awk '{ printf "https://thing.com/c/%s/%s", $1, $2 }'
Run Code Online (Sandbox Code Playgroud)

我距离bash专家还很远,也不知道这里发生了什么。我从命令行(而不是从调用脚本)尝试过这种方法,并且可以正常工作。我真的很茫然。

编辑:我用URLID1(以及2替换SCANID1)。它们是复制粘贴错误。

Gil*_*il' 5

正如乔纳森·莱夫勒(Jonathan Leffler)在评论中所说,最可能的解释是数据中存在Windows(CRLF)行尾。Unix使用LF行尾。在终端上,CR字符将光标移动到该行的开头,而不将其移动到下一行。例如,如果您运行

printf '%s\r%s\n' wibble foo
Run Code Online (Sandbox Code Playgroud)

您会看到fooble因为wibble被显示,然后光标移动到该行foo的开头并覆盖的开头wibble

您的脚本与示例输出不完全匹配,但似乎该行

echo https://thing.com/c/${SCANID1}/${SCANID2}
Run Code Online (Sandbox Code Playgroud)

产生具有斜线和行首的值的输出SCANID2。发生这种情况是因为SCANID1end 的值以CR字符结尾。

为了使脚本对Windows行尾具有鲁棒性,请删除任何CR字符,或者至少删除行尾的任何CR字符(如果在其他位置有CR字符,则数据还有其他问题)。在bash中,如果值以CR结尾,则"${var%$'\r'}"给出var负CR 值;如果值不以CR结尾,则给出不变值。

我建议尽早剥离CR,以避免出现任何问题:

URL1=$(myCurl "${1}"); URL1=${URL1%$'\r'}
URL2=$(myCurl "${2}"); URL2=${URL2%$'\r'}
Run Code Online (Sandbox Code Playgroud)

(您不能在单个分配中结合使用命令替换和截断。)

但是您也可以在awk阶段执行此操作:

SCANID1=$(echo "$URL1" | awk -F 'https://thing.com/' '{print sub("\r", "", $2)}')
Run Code Online (Sandbox Code Playgroud)

请注意,这里不需要调用awk。

SCANID1=${URL1#*https://*/}
Run Code Online (Sandbox Code Playgroud)