Tcsh 脚本上次退出代码 ($?) 值正在重置
Tcsh Script Last Exit Code ($?) value is resetting
我正在 运行使用 tcsh 创建以下脚本。在我的 while 循环中,我正在 运行 宁我创建的 C++ 程序,并将 return 根据某些事情不同的退出代码。虽然它 return 的退出代码为 0,但我希望脚本增加计数器并再次 运行 程序。
#!/bin/tcsh
echo "Starting the script."
set counter = 0
while ($? == 0)
@ counter ++
./auto $counter
end
我已经验证我的程序在某个点后确实 returning 退出代码 = 1。但是,while 循环中的条件由于某种原因一直评估为 true 并且 运行ning.
我发现如果我在循环末尾添加以下行,然后用这个新变量替换 while 循环中的条件检查,它就可以正常工作。
while ($return_code == 0)
@ counter ++
./auto $counter
set return_code = $?
end
为什么我不能只使用 $?直接地? 运行 在我的自定义程序和检查导致 $ 的循环条件之间是否执行了另一个幕后操作?更改值?
这很奇怪。
我已将您的示例更改为我认为可以更清楚地说明问题的内容。 (注意 $?
是 $status
的别名。)
#!/bin/tcsh -f
foreach i (1 2 3)
false
# echo false status=$status
end
echo Done status=$status
输出是
Done status=0
如果我取消注释循环中的 echo
命令,输出为:
false status=1
false status=1
false status=1
Done status=0
(当然,循环中的 echo
无论如何都会破坏逻辑,因为 echo
命令成功完成并将 $status
设置为零。)
我认为发生的事情是终止循环的end
作为语句执行,它设置$status
($?
) 到 0.
我看到 tcsh
和 bsd-csh
的行为相同。
在命令后立即将 $status
的值保存在另一个变量中是一个很好的解决方法——并且可以说是一种更好的方法,因为 $status
非常脆弱,并且几乎如果你看着它,真的会被破坏。
请注意,我在 #!
行中添加了一个 -f
选项。这可以防止 tcsh
获取您的初始化文件(.cshrc
或 .tcshrc
),这被认为是一种很好的做法。 (sh/bash/ksh/zsh 的情况并非如此,它赋予 -f
完全不同的含义。)
题外话:多年来我经常使用 tcsh
,既作为我的交互式登录 shell 又用于编写脚本。我不会预料到 end
会设置 $status
。这不是我第一次不得不通过反复试验找出 tcsh
或 csh
的行为方式并对结果感到惊讶。这是我切换到 bash
进行交互和脚本使用的原因之一。我不会告诉你也这样做,但你可能想读读 Tom Christiansen 的经典著作“csh.whynot”。
略shorter/simpler解释:
回想一下 tcsh/csh EACH 命令(包括 shell 内置命令)return 一个状态。因此 $? ($status 的别名)由 'if' 语句、'for' 循环、赋值、...
更新
从实用的角度来看,直接使用$来限制使用会更好吗?命令执行后的 if 语句:
do-something
if ( $status == 0 )
...
endif
在所有其他情况下,捕获变量中的状态,并仅使用该变量
do-something
something_status=$?
if ( $something_status == 0 )
...
endif
为了扩展 $status,即使 if 语句中的条件测试也会修改状态,因此以下对 $status 的重复测试不会永远命中 '$status == 5',即使执行 -某些东西会 return 状态 5
do-something
if ( $status == 2 ) then
echo FOO
else if ( $status == 5 ) then
echo BAR
endif
我正在 运行使用 tcsh 创建以下脚本。在我的 while 循环中,我正在 运行 宁我创建的 C++ 程序,并将 return 根据某些事情不同的退出代码。虽然它 return 的退出代码为 0,但我希望脚本增加计数器并再次 运行 程序。
#!/bin/tcsh
echo "Starting the script."
set counter = 0
while ($? == 0)
@ counter ++
./auto $counter
end
我已经验证我的程序在某个点后确实 returning 退出代码 = 1。但是,while 循环中的条件由于某种原因一直评估为 true 并且 运行ning.
我发现如果我在循环末尾添加以下行,然后用这个新变量替换 while 循环中的条件检查,它就可以正常工作。
while ($return_code == 0)
@ counter ++
./auto $counter
set return_code = $?
end
为什么我不能只使用 $?直接地? 运行 在我的自定义程序和检查导致 $ 的循环条件之间是否执行了另一个幕后操作?更改值?
这很奇怪。
我已将您的示例更改为我认为可以更清楚地说明问题的内容。 (注意 $?
是 $status
的别名。)
#!/bin/tcsh -f
foreach i (1 2 3)
false
# echo false status=$status
end
echo Done status=$status
输出是
Done status=0
如果我取消注释循环中的 echo
命令,输出为:
false status=1
false status=1
false status=1
Done status=0
(当然,循环中的 echo
无论如何都会破坏逻辑,因为 echo
命令成功完成并将 $status
设置为零。)
我认为发生的事情是终止循环的end
作为语句执行,它设置$status
($?
) 到 0.
我看到 tcsh
和 bsd-csh
的行为相同。
在命令后立即将 $status
的值保存在另一个变量中是一个很好的解决方法——并且可以说是一种更好的方法,因为 $status
非常脆弱,并且几乎如果你看着它,真的会被破坏。
请注意,我在 #!
行中添加了一个 -f
选项。这可以防止 tcsh
获取您的初始化文件(.cshrc
或 .tcshrc
),这被认为是一种很好的做法。 (sh/bash/ksh/zsh 的情况并非如此,它赋予 -f
完全不同的含义。)
题外话:多年来我经常使用 tcsh
,既作为我的交互式登录 shell 又用于编写脚本。我不会预料到 end
会设置 $status
。这不是我第一次不得不通过反复试验找出 tcsh
或 csh
的行为方式并对结果感到惊讶。这是我切换到 bash
进行交互和脚本使用的原因之一。我不会告诉你也这样做,但你可能想读读 Tom Christiansen 的经典著作“csh.whynot”。
略shorter/simpler解释:
回想一下 tcsh/csh EACH 命令(包括 shell 内置命令)return 一个状态。因此 $? ($status 的别名)由 'if' 语句、'for' 循环、赋值、...
更新从实用的角度来看,直接使用$来限制使用会更好吗?命令执行后的 if 语句:
do-something
if ( $status == 0 )
...
endif
在所有其他情况下,捕获变量中的状态,并仅使用该变量
do-something
something_status=$?
if ( $something_status == 0 )
...
endif
为了扩展 $status,即使 if 语句中的条件测试也会修改状态,因此以下对 $status 的重复测试不会永远命中 '$status == 5',即使执行 -某些东西会 return 状态 5
do-something
if ( $status == 2 ) then
echo FOO
else if ( $status == 5 ) then
echo BAR
endif