我想要做的是调用PS1
中的函数来更新函数内的变量。然后我喜欢使用该变量向PS1添加另一行。像吼叫:
my_func(){
var="_RED_"
echo "hello in red"
}
PS1="\[\033]0;\w\007\]"
PS1+='$(my_func)'
if [ $var = "_RED_" ]; then # here I want to use that var
PS1+="\[$(tput setaf 124)\] red"
fi
这样做的原因是将不可打印的字符\[
和\]
从函数中移出,以防止重叠由\[ \]
答案 0 :(得分:3)
您可以绝对更新shell函数内的全局变量 - 函数内的所有赋值修改全局变量,除非使用local
或declare
变量创建新范围。
然而,这里的问题是,您不能在与稍后尝试阅读var
的代码相同的shell进程中运行您的函数(尽管它是否实际上是"稍后& #34;或者不是一个单独的问题)!当您使用命令替换 - $()
中的$(my_func)
时 - 您正在创建一个新的分叉子流程来运行该功能。当该子进程退出时,对其所做的变量值的所有更改都将丢失。
但是,您可以使用命令替换 not 来解决这个问题。请考虑以下内容,它使用PROMPT_COMMAND
挂钩来指定PS1
:
# code to run before each time a prompt is printed
PROMPT_COMMAND='build_ps1_func'
# rewrite your function to write to a named variable, not stdout
my_func(){
local outvar=$1; shift # named variable to write stdout to
var="_RED_" # hardcoded global to update, per question
printf -v "$outvar" '%s' "hello in red"
}
build_ps1_func() {
local your_str # define your_str as a local variable
my_func your_str # call my_func, telling it to write output to your_str
PS1="\[\033]0;\w\007\]"
PS1+="$your_str"
if [ $var = "_RED_" ]; then # using that variable here
PS1+="\[$(tput setaf 124)\] red"
fi
}
答案 1 :(得分:0)
我想要做的是调用PS1中的函数来更新函数内部的变量。然后我喜欢使用该变量向PS1添加另一行。
从您的示例代码中,我想您的意思是您希望在为PS1
赋值的过程中执行涉及shell函数的命令扩展。 [update:]由于您已经标记了问题[bash],我们假设您对GNU Bash的行为特别感兴趣,这与完全符合要求的POSIX shell的行为不同这个区域。 在这种情况下,重要的是要认识到在设置/修改 PS1
的值时,一次执行命令扩展,而不是每次显示PS1
。你的措辞和具体语法让我怀疑你有不同的期望。
考虑这部分代码:
PS1="\[\033]0;\w\007\]" PS1+='$(my_func)'
因为它出现在单引号中,所以$(my_func)
在附加到提示字符串时不受命令扩展或任何其他扩展的限制。 尽管在将值附加到 与完全符合要求的POSIX shell不同, Bash将在打印之前对提示字符串执行命令替换。 PS1
之前删除了单引号,但这并不意味着它将在以后进行扩展。
现在,因为函数体是一个花括号复合命令,如果它被执行,那么它确实会在当前shell中设置var
的值,并且该函数在函数返回后将可见。然而,
var
,您也要测试$var
的值,与您的函数设置的值不同。相反,请考虑代码的其他片段:
PS1+="\[$(tput setaf 124)\] red"
因为在这种情况下整个字符串是双引号,所以内容明确地受命令扩展的影响。如果执行此操作,$(tput setaf 124)
将替换为运行tput setaf 124
的输出。这将在PS1
的值被修改时发生,而不是每次显示其值时都会发生。
虽然您可以生成包含ANSI转义序列的提示,但您无法按照您尝试的方式执行此操作。由于您的具体需求尚不清楚,我不愿意提出一个特别的选择。