函数 ping+() 到 .bashrc 不起作用
Function ping+() into .bashrc doesn't work
我有这个问题。
我的机器是windows10,最新版本。
我安装了 cygwin,在我的 bashrc 中我有这个功能:
ping+()
{
host=
par_1=
par_2=
par_3=
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}
工作正常:
Luca[~] :> ping+ www.google.it
[2018-11-28 | 20:41:23] Pinging www.google.it [74.125.71.94] with 32 bytes of data:
[2018-11-28 | 20:41:23] Reply from 74.125.71.94: bytes=32 time=28ms TTL=43
[2018-11-28 | 20:41:24] Reply from 74.125.71.94: bytes=32 time=31ms TTL=43
[2018-11-28 | 20:41:25] Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26] Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26] Ping statistics for 74.125.71.94:
[2018-11-28 | 20:41:26] Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
[2018-11-28 | 20:41:26] Approximate round trip times in milli-seconds:
[2018-11-28 | 20:41:26] Minimum = 28ms, Maximum = 31ms, Average = 29ms
但是如果我在 "ubuntu windows filesystem" 将此代码放入 .bashrc 中,我会收到此错误:
luca[/mnt/c/Users/Luca] :> source /home/luca/.bashrc
ping+(): command not found
很可能 "ping" 后的“+”不被接受。
我该如何解决这个问题?
谢谢
卢卡
这是名称中带有 '+'
字符的 shell 函数与 bash 的 extglob
选项之间奇怪交互的结果。很可能您在 Cygwin 下的 shell 中禁用了 extglob
,并在 "ubuntu windows filesystem" 配置中启用了
我还没弄明白为什么 extglob
有这种特殊的副作用。这可能是 bash 中的错误。 bash
接受 ping+
作为函数名甚至可能是一个错误,具体取决于相关标准和其他文档对函数名正确语法的说明。
最简单的解决方案是使用不以 +
字符结尾的名称。
如果您真的想为您的函数使用名称 ping+
,解决方法是在定义函数时取消设置 extglob
选项。 (无论是否设置了 extglob
,您仍然可以使用名称 ping+
调用它。)
例如,您可以在 .bashrc
:
shopt -u extglob
ping+() {
host=
par_1=
par_2=
par_3=
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}
shopt -s extglob
(这会强制设置 extglob
。如果你想让它保持初始状态,那就有点复杂了。你必须解析 shopt extglob
的输出以确定无论是已设置还是未设置。但您可能还是想无条件地设置它。)
另一种解决方案是使用可执行的 shell 脚本而不是函数。例如,这个脚本相当于你的函数:
#!/bin/bash
host=""
par_1=""
par_2=""
par_3=""
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
使用上述内容创建一个名为 ping+
的文件,使用 chmod +x
使其可执行,并将其复制到 $PATH
中的目录,例如 $HOME/bin
。 (不需要安装在系统目录,如/usr/bin
。如果你想让它对系统上的所有用户都可用,你可以将它安装在系统范围的目录,如/usr/local/bin
. /usr/bin
目录用于操作系统本身提供的命令。)
之所以可行,是因为命令名称的规则比 shell 函数名称的规则更简单且限制更少。
这是一个更简单、更可靠的版本(它避免了参数中 shell 元字符的任何问题)。
#!/bin/bash
ping "$@" | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
或更好(因为 xargs
可以启用命令替换攻击,正如 Charles Duffy 指出的那样):
#!/bin/bash
ping "$@" | while read -r line ; do echo "[$(date +'%Y-%m-%d | %H:%M:%S')] $line" ; done
我有这个问题。 我的机器是windows10,最新版本。
我安装了 cygwin,在我的 bashrc 中我有这个功能:
ping+()
{
host=
par_1=
par_2=
par_3=
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}
工作正常:
Luca[~] :> ping+ www.google.it
[2018-11-28 | 20:41:23] Pinging www.google.it [74.125.71.94] with 32 bytes of data:
[2018-11-28 | 20:41:23] Reply from 74.125.71.94: bytes=32 time=28ms TTL=43
[2018-11-28 | 20:41:24] Reply from 74.125.71.94: bytes=32 time=31ms TTL=43
[2018-11-28 | 20:41:25] Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26] Reply from 74.125.71.94: bytes=32 time=29ms TTL=43
[2018-11-28 | 20:41:26] Ping statistics for 74.125.71.94:
[2018-11-28 | 20:41:26] Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
[2018-11-28 | 20:41:26] Approximate round trip times in milli-seconds:
[2018-11-28 | 20:41:26] Minimum = 28ms, Maximum = 31ms, Average = 29ms
但是如果我在 "ubuntu windows filesystem" 将此代码放入 .bashrc 中,我会收到此错误:
luca[/mnt/c/Users/Luca] :> source /home/luca/.bashrc
ping+(): command not found
很可能 "ping" 后的“+”不被接受。 我该如何解决这个问题? 谢谢 卢卡
这是名称中带有 '+'
字符的 shell 函数与 bash 的 extglob
选项之间奇怪交互的结果。很可能您在 Cygwin 下的 shell 中禁用了 extglob
,并在 "ubuntu windows filesystem" 配置中启用了
我还没弄明白为什么 extglob
有这种特殊的副作用。这可能是 bash 中的错误。 bash
接受 ping+
作为函数名甚至可能是一个错误,具体取决于相关标准和其他文档对函数名正确语法的说明。
最简单的解决方案是使用不以 +
字符结尾的名称。
如果您真的想为您的函数使用名称 ping+
,解决方法是在定义函数时取消设置 extglob
选项。 (无论是否设置了 extglob
,您仍然可以使用名称 ping+
调用它。)
例如,您可以在 .bashrc
:
shopt -u extglob
ping+() {
host=
par_1=
par_2=
par_3=
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
}
shopt -s extglob
(这会强制设置 extglob
。如果你想让它保持初始状态,那就有点复杂了。你必须解析 shopt extglob
的输出以确定无论是已设置还是未设置。但您可能还是想无条件地设置它。)
另一种解决方案是使用可执行的 shell 脚本而不是函数。例如,这个脚本相当于你的函数:
#!/bin/bash
host=""
par_1=""
par_2=""
par_3=""
ping $host $par_1 $par_2 $par_3 | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
使用上述内容创建一个名为 ping+
的文件,使用 chmod +x
使其可执行,并将其复制到 $PATH
中的目录,例如 $HOME/bin
。 (不需要安装在系统目录,如/usr/bin
。如果你想让它对系统上的所有用户都可用,你可以将它安装在系统范围的目录,如/usr/local/bin
. /usr/bin
目录用于操作系统本身提供的命令。)
之所以可行,是因为命令名称的规则比 shell 函数名称的规则更简单且限制更少。
这是一个更简单、更可靠的版本(它避免了参数中 shell 元字符的任何问题)。
#!/bin/bash
ping "$@" | xargs -n1 -i bash -c 'echo [`date +"%Y-%m-%d | %H:%M:%S"`] " {}"'
或更好(因为 xargs
可以启用命令替换攻击,正如 Charles Duffy 指出的那样):
#!/bin/bash
ping "$@" | while read -r line ; do echo "[$(date +'%Y-%m-%d | %H:%M:%S')] $line" ; done