Shell 函数带中横线问题排查

Shell 中编写的函数,如果函数名中带了中横线,在使用 /bin/sh 执行时会报错。

➜  subprocess git:(master) ✗ cat kubectl.sh

_kubectl_api-resources()
{
    hostname
}

_kubectl_api-resources
➜  subprocess git:(master) ✗ sh kubectl.sh
kubectl.sh: line 5: _kubectl_api-resources': not a valid identifier
</code></pre>
<p>根据 POSIX 的标准,函数名要符合以下的规范。</p>
<blockquote>
<p><strong>3.231 Name</strong>
In the shell command language, a word consisting solely of underscores, digits, and alphabetics from the portable character set. The first character of a name is not a digit.</p>
</blockquote>
<p>可以看到,中横线不在标准支持的范围内。因此使用 <code>/bin/sh</code> 执行时,会看到我们上面列出的错误。</p>
<p>但是 <code>bash</code> 和 <code>zsh</code> 却可以支持函数中的中横线。</p>
<pre><code class="language-sh">➜  subprocess git:(master) ✗ cat kubectl.sh

_kubectl_api-resources()
{
    hostname
}

_kubectl_api-resources
➜  subprocess git:(master) ✗ sh kubectl.sh
kubectl.sh: line 5: _kubectl_api-resources': not a valid identifier
➜  subprocess git:(master) ✗ bash kubectl.sh
bogon
➜  subprocess git:(master) ✗ zsh kubectl.sh
bogon

因此,如果我们希望我们的 Shell 脚本具有更好的可移植性,那就尽量避免在函数命名时使用中横线。

Python 使用 subprocess.Popen 执行 shell 时,若选择了 shell=True 选项,则会默认使用 /bin/sh。因此在遇到使用了中横线的 shell 函数时,也会报错。如果希望使用 /bin/bash 则需要设置 executable 参数,示例如下:

import subprocess

def bash_command(cmd):
    subprocess.Popen(cmd, shell=True, executable='/bin/bash')

bash_command('a="Apples and oranges" && echo "${a/oranges/grapes}"')

如果这个方法不生效,还可以使用下面的方案。

import subprocess

def bash_command(cmd):
    subprocess.Popen(['/bin/bash', '-c', cmd])

参考资料

Original: https://www.cnblogs.com/cocowool/p/shell-function-with-hyphen.html
Author: Cocowool
Title: Shell 函数带中横线问题排查

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529579/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球