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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么这个用于着色文本的bash函数只打印整个字符串的第一个单词?相关的知识,希望对你有一定的参考价值。

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

#!/usr/bash

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

normalMessage="Everything fine"

echo_message() {

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

}

echo_message $normalMessage 

我的输出是:

Everything
答案

对我来说,我不得不更改“#!/ 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"
另一答案

正如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陷阱,包括不带引号的扩展。

另一答案

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

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

另一答案

你引用错了。

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

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

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

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

echo_message "$normalMessage"

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

以上是关于为什么这个用于着色文本的bash函数只打印整个字符串的第一个单词?的主要内容,如果未能解决你的问题,请参考以下文章

在heredocs中着色,bash

为啥它只打印文本文件的一个单词而不是整个文本文件到 html 文件

cat 文件到终端并为特定单词着色[重复]

在 BASH 下运行的程序的颜色输出 [关闭]

BASH输出着色显示

我如何只打印出消息而不是整个文本[重复]