如果使用absolut路径运行,Bash脚本会出现意外行为
因此,我们有一个脚本,它应该根据用户输入更改linux机器的IP。必须验证此用户输入 如果脚本在它所在的目录中运行,那么一切都会按预期运行,但一旦它以绝对路径运行,它似乎在某些点上会中断 我已经尝试使用调试选项set-x,但是输出几乎保持不变如果使用absolut路径运行,Bash脚本会出现意外行为,bash,undefined-behavior,Bash,Undefined Behavior,因此,我们有一个脚本,它应该根据用户输入更改linux机器的IP。必须验证此用户输入 如果脚本在它所在的目录中运行,那么一切都会按预期运行,但一旦它以绝对路径运行,它似乎在某些点上会中断 我已经尝试使用调试选项set-x,但是输出几乎保持不变 read-p“请输入网络掩码(CIDR格式):”网络掩码 如果[!$(回显“$netmask”| egrep”^([12]?[0-9]?)$”); 然后 subnetok=0 fi 如果[“$subnetok”=“0”]; 然后 echo-e“\033[4
read-p“请输入网络掩码(CIDR格式):”网络掩码
如果[!$(回显“$netmask”| egrep”^([12]?[0-9]?)$”);
然后
subnetok=0
fi
如果[“$subnetok”=“0”];
然后
echo-e“\033[41m\033[39m子网掩码无效!\033[0m”
睡眠1
返回1
fi
如果脚本在目录中运行,则这是调试输出:
++echo 24
++白鹭“^([12]?[0-9]?)$”
+ '[' '!' 24 ']'
+ '[' '' == 0 ']'
如果脚本以绝对路径运行,则这是调试输出
+++echo 24
+++egrep--颜色=自动“^([12]?[0-9]?)$”
++ '[' '!' 24 ']'
++ '[' 0 == 0 ']'
++echo-e“子网掩码无效”
我希望输出与相同的数字相同:
通过使用绝对路径运行,我的意思是./usr/local/script/script.sh,而不是将cd放入/usr/local/script/然后./script.sh
不同之处在于,在一种情况下,您正在执行脚本,而在另一种情况下,您正在寻找脚本的来源。有关更多信息,请参阅
当您运行/script.sh
时,在点和斜杠之间没有空格,您是在一个新的shell中执行脚本。当您运行/usr/local/script/script.sh
时,您是在当前shell中寻找脚本。例如,如果您在当前shell中设置了一个别名d不会出现在新的shell中,例如别名egrep='egrep--color=auto'
。这就是为什么会有差异
有关连的问题:
寻源和执行脚本都将逐行运行脚本中的命令,就像您逐行手动键入这些命令一样
区别在于:
- 在执行打开新shell的脚本时,在新shell中键入命令,将输出复制回当前shell,然后关闭新shell。对环境的任何更改仅在新shell中生效,并且在新shell关闭后将丢失
- 编写脚本源代码时,您正在当前shell中键入命令。对环境的任何更改都将生效并保留在当前shell中
/script.sh
时,在点和斜杠之间没有空格,您是在一个新的shell中执行脚本。当您运行/usr/local/script/script.sh
时,您是在当前shell中寻找脚本。例如,如果您在当前shell中设置了一个别名d不会出现在新的shell中,例如别名egrep='egrep--color=auto'
。这就是为什么会有差异
有关连的问题:
寻源和执行脚本都将逐行运行脚本中的命令,就像您逐行手动键入这些命令一样
区别在于:
- 在执行打开新shell的脚本时,在新shell中键入命令,将输出复制回当前shell,然后关闭新shell。对环境的任何更改仅在新shell中生效,并且在新shell关闭后将丢失
- 编写脚本源代码时,您正在当前shell中键入命令。对环境的任何更改都将生效并保留在当前shell中
使用以下命令运行脚本时:
. /usr/local/script/script.sh
这将使用
命令,该命令在当前shell中运行脚本(相当于source
)。也就是说,它在交互式shell中运行脚本,而不是在新shell中运行脚本。请参阅:
这(至少)有两个影响:
- 当前的shell是交互式的,并且显然有一个为
定义的别名,这使得事情有点奇怪。这不是一个真正的问题,只是奇怪而已egrep
- 当前shell显然已经有了变量
的定义,它是“0”。这可能是上次以这种方式运行脚本时留下的。这就是问题的原因subnetok
subnetok
,而不仅仅是假设它是未定义的:
subnetok=1
if ...
或者,如果您不需要该变量来执行任何其他操作,您可以跳过它并立即处理该条件:
if [ ! $(echo "$netmask" | egrep "^([12]?[0-9]?)$") ]; # See below for alternatives
then
echo -e "\033[41m\033[39m Subnetmask is invalid!\033[0m"
...
其他建议:
- 在不使用
的情况下运行脚本:/usr/local/script/script.sh
- 为脚本指定一个正确的shebang行(如果它还没有),指定bash shell(即
或#!/bin/bash
)#!/usr/bin/env bash
- 使用更好的方法检查子网的有效性,如:
或(仅限bash):if ! echo "$netmask" | grep -Eq "^[12]?[0-9]?$"
- 不要使用
,因为它不可移植(即使在同一操作系统的不同版本、shell模式等之间)。请改用echo-e
(我建议对包含反斜杠的字符串使用单引号,因为在某些情况下它们是printf
if ! [[ "$netmask" =~ ^[12]?[0-9]?$ ]]
printf '\033[41m\033[39m Subnetmask is invalid!\033[0m'