我在函数中的多个变量不会表示为别名。我认为我的语法有问题

我在函数中的多个变量不会表示为别名。我认为我的语法有问题

在 中bashrc,我有一个警报函数,它可以采用 3 个变量:

a () {
    local $1="${1:-3600}"
   local $2="${2:-paa}"
   local $3="${3:-alarm}"
    sleep "$1" && $2 && $3
}
alias pah='pactl set-card-profile 0 output:hdmi-stereo'
alias paa='pactl set-card-profile 0 output:analog-stereo'
alias alarm='vlc ~/alarm.mp3'

在命令行上,以下命令可以很好地执行我的别名。

sleep 3600 && paa && alarm

但是,当我尝试制作上面显示的函数的这一部分时,我收到此错误:

bash: pah: command not found

另外:1 美元、2 美元、3 美元变量应默认为3600,帕阿, 和警报

我也很困惑如何使用 $3 输入调用此函数,同时允许默认 $1 和 $2。

IE

a null null alarm2

转发说明:我在 Stack Overflow 上发布了这个问题,但意识到这个问题可能属于 Unix & Linux 堆栈交换。

答案1

我不明白你如何从运行中获得此输出a:你是否发布了不同版本的输出?但无论如何我确实看到了代码有什么问题。

第一个问题是它local $1=…并没有按照你的想法去做。它设置一个名称为第一个参数的变量,但不设置第一个参数。例如,如果将函数调用为a foo,则第一行将局部变量设置foo为值foo。如果你a不带任何参数调用,你会得到

bash: local: `=3600': not a valid identifier

(以及更多错误)因为 的 左边=是一个空字符串,并且该空字符串不是变量的有效名称。

您不能使用赋值语法来设置编号参数:local 1=…也不起作用。您需要为变量命名或使用set内置函数一次性设置所有编号参数。

a () {
    local delay="${1:-3600}"
    local first_command_to_split_and_glob="${2:-paa}"
    local second_command_to_split_and_glob="${3:-alarm}"
    sleep "$delay" && $first_command_to_split_and_glob && $second_command_to_split_and_glob
}

第二个问题是别名只有在明确出现在命令开头时才会展开。它们不是从其他一些扩展的结果(例如获取变量的值)扩展而来的。

call 还有一个问题$first_command_to_split_and_glob,那就是它只适用于简单的情况。它在空白处分割变量的值(即传递给函数的参数),然后将每一部分解释为通配符模式,如果该模式至少匹配一个文件名,则它会扩展该通配符模式。例如,尝试显示名为、和的a 2 'cat "file name with spaces"'文件的内容。引号外的变量扩展应用“split+glob”操作:它既不产生变量的值也不对该值执行评估,而是中间的东西很少有用。看"filenamewithspaces"为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?更多细节。

要解决这两个问题,请使用evalon 字符串。请注意"$first_command"和周围的双引号,"$second_command"以避免 split+glob。

a () {
    local delay="${1:-3600}"
    local first_command="${2:-paa}"
    local second_command="${3:-alarm}"
    sleep "$delay" && eval "$first_command" && eval "$second_command"
}

最后,要传递空参数,请使用引号分隔空字符串。例如:

a '' pah

等待 3600 秒,然后运行pah,然后运行alarm

相关内容