运行脚本和源脚本之间的bash printf输出的差异

时间:2011-08-30 02:50:57

标签: bash unicode printf

我似乎无法找到两种不同方式的脚本之间的区别。

这是脚本(名为test.sh):

#! /bin/bash
printf "%b\n" "\u5A"

当脚本来源时:

. test.sh
> Z         ## Result I want ##

运行脚本时:

./test.sh
> \u5A      ## Result I get ##

我希望运行脚本能够提供源脚本的结果...我需要设置/更改哪些设置?

6 个答案:

答案 0 :(得分:1)

您不应该使用\x代替\u吗? printf "%b\n" "\x5A"对我来说在这两种情况下都可以正常工作。

答案 1 :(得分:1)

你可能会得到不同版本的printf;您从中获取的脚本可能是/ bin / sh脚本,而不是正确的Bash脚本?

答案 2 :(得分:1)

(这里有完全不同的想法,所以我将其作为另一个答案发布。)

尝试在命令行运行这些:

builtin printf "%b\n" "\u5A"
/usr/bin/env printf "%b\n" "\u5A"

printf既是shell内置函数又是可执行文件,您可能会获得不同的内容,具体取决于您是源代码还是运行脚本。要找到答案,请在脚本中插入并以单向方式运行:

type printf

当你在这里时,你也可以插入这一行:

echo $SHELL

这将揭示你是否每个三人组获得不同的炮弹。

答案 3 :(得分:1)

哈哈!!! 我终于追查了这个问题!如果有兴趣离开页面,请提前阅读。

这些 命令可以正确翻译\u

. ./test.sh                         ## Sourcing the script, hash-bang = #! /bin/sh
. ./test.bash                       ## Sourcing the script, hash-bang = #! /bin/bash
./test                              ## Running the script with no hash-bang

以下所有内容产生相同的结果,因为它们 NOT 翻译\u

./test.sh                           ## Script is run from an interactive shell but in a non-interactive shell

## test.sh has first line: #! /bin/sh
/bin/sh -c "./test.sh"              ## Running the script in a non-interactive sh shell
/bin/sh -lc "./test.sh"             ## Running the script in a non-interactive, login sh shell
/bin/sh -c ". ./test.sh"            ## Sourcing the file in a non-interactive sh shell
/bin/sh -lc ". ./test.sh"           ## Sourcing the file in a non-interactive, login sh shell

## test.bash has first line: #! /bin/bash
/bin/bash -c "./test.bash"          ## Running the script in a non-interactive bash shell
/bin/bash -lc "./test.bash"         ## Running the script in a non-interactive, login bash shell
/bin/bash -c ". ./test.bash"        ## Sourcing the file in a non-interactive bash shell
/bin/bash -lc ". ./test.bash"       ## Sourcing the file in a non-interactive, login bash shell

## And from ***tripleee*** (thanks btw):
/bin/sh --norc; . ./test.sh         ## Sourcing from an interactive sh shell without the ~/.bashrc file read
/bin/bash --norc; . ./test.bash     ## Sourcing from an interactive bash shell without the ~/.bashrc file read

获得正确翻译的唯一方法是运行脚本而不 hash-bang ......我终于找到了原因!如果没有 hash-bang ,我的系统会选择默认的shell,即btw NOT /bin/bash ...原来是/opt/local/bin/bash ..两个不同版本的bash!

最后,我删除了OSX /bin/bash [v3.2.48(1)]并将其替换为MacPorts /opt/local/bin/bash [v4.2.10(2)],现在运行脚本可以正常工作!它实际上解决了我已经遇到的大约10-15个其他问题(例如${var,,}read sN1 charcomplete -EC "echo ' '"以及我在脚本中散布的许多其他命令{{1} } amd ~/.bashrc)。老实说,当我使用关联数组的脚本突然出现在我身上时,我真的应该注意到...... 我有多愚蠢!?

我现在一直在使用bash v4,而且我的Lion升级版已经降级为v3(请使用Apple程序!)......呃,我感到很惭愧!每个人仍然使用bash v3,升级!! bash v4在版本3上有许多很多漂亮的升级。输入 ~/.profile 以查看您正在运行的版本。一个优点是现在bash可以将bash --version翻译成 Unicode!

感谢大家的帮助!

- Aesthir

答案 4 :(得分:0)

尝试删除第一行中的空格,我似乎记得可能会导致问题。我猜是因为那个空间,你不会受到打击,但是sh。

答案 5 :(得分:0)

很高兴你解决了它。不过,您可能正在寻找便携式解决方案。

假设您总是使用相同的格式化字符串,我们可以放弃它,并使用类似的东西;

printf () {
  # Discard format string
  shift
  perl -CSD -le '
    print map { s/^\\u//; chr(hex($_)) } @ARGV' "$@"
}

编辑添加:您只需在现有脚本的开头添加此功能定义,覆盖内置printf。显然,如果你还使用printf作为其他东西,这个特殊用途的替代品还不够好。

您可以将该功能重命名为uprintf或其他内容。它只是将一系列十六进制代码转换为相应的Unicode字符,丢弃任何\u前缀。