为什么这个用于着色文本的bash函数只打印整个字符串的第一个单词?

时间:2018-05-09 18:54:34

标签: linux bash shell scripting

我试图创建一个函数来打印绑定到某种颜色的变量的消息。消息变量作为此函数的参数传递。问题是我只能将文本提取到第一个空格(只有第一个消息字)。我的脚本看起来像这样:

#!/usr/bash

lbGREEN='\e[1;92m'
NC='\e[0m'

normalMessage="Everything fine"

echo_message() {

    echo -e  ${lbGREEN}$1${NC}

}

echo_message $normalMessage 

我的输出是:

Everything

4 个答案:

答案 0 :(得分:3)

对我来说,我必须更改“#!/ bin / bash”的标题,但显然这对你来说不是问题。

在你的回音中,你只用$ 1打印第一个单词,如果你把它改成$ 2,你将打印第二个单词(参数),依此类推。

您可以在引号内传递名称或使用$ @

打印所有参数

解决方案1(使用$ @):

lbGREEN='\e[1;92m'
NC='\e[0m'
normalMessage="Everything fine"
echo_message() {
    echo -e  ${lbGREEN}$@${NC}
}
echo_message $normalMessage

解决方案2(带引号):

lbGREEN='\e[1;92m'
NC='\e[0m'
normalMessage="Everything fine"
echo_message() {
    echo -e  ${lbGREEN}$1${NC}
}
echo_message "$normalMessage"

答案 1 :(得分:3)

正如Inian在评论中指出的那样,你的问题是无引号变量扩展

echo_message $normalMessage 

变为

echo_message Everything fine

一旦变量扩展,意味着输入字符串的每个单词都作为单独的参数被读入。如果发生这种情况$1=Everything$2=fine

这是通过对您的变量进行双引号来修复的,这允许扩展,但这意味着扩展的结果仍将作为一个参数读取。

echo_message "$normalMessage"

变为

echo_message "Everything fine"

喜欢这个$1=Everything fine

将来,我建议使用https://www.shellcheck.net/或shellcheck的CLI版本,它将突出显示所有类型的常见bash陷阱,包括不带引号的扩展。

答案 2 :(得分:1)

你应该看看https://stackoverflow.com/a/6212408/1428602

恕我直言,$ 1只返回第一个字,所以你必须使用循环或尝试使用$ *

答案 3 :(得分:1)

你引用错误。

如果要模拟echo的行为,您的函数应接受多个参数,并将它们全部打印出来。目前它只评估第一个参数,所以我建议改用$*。您还需要将参数括在双引号中以保护任何特殊字符:

echo_message() {
    echo -e  "${lbGREEN}$*${NC}"
}

特殊变量$*扩展为所有参数,用空格(或更准确地说,$ IFS的第一个字符,通常是空格字符)分隔。请注意,您几乎总是希望"$@"而不是"$*",这是后者也是正确的罕见情况之一,但如果将IFS设置为非语义,则语义略有不同标准值。

现在该函数支持多个参数,并将它们全部打印为绿色,用空格分隔。但是,我建议您在调用函数时引用该参数:

echo_message "$normalMessage"

虽然现在可以正确处理$normalMessage中的空格,但!等其他特殊字符仍然需要引号。