Bash
對於 select 命令,腳本文件中的 TMOUT 行為異常。如何解決?
更新- 看起來這是 bash 4.3.42 的特殊之處,因為它適用於 4.3.46。為那些將來遇到同樣問題的人留下這篇文章。
當我在 bash 命令行中執行此命令時,它可以正常工作:
% (TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s) 1) a 2) b 3) c #? no selection % _
結果:不顯示任何選擇並返回命令行。
但是,當我將它放置一個腳本並執行它時,它會反復請求選擇。
% cat a.sh #!/bin/bash (TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s) % ./a.sh
結果:
1) a 2) b 3) c #? 1) a 2) b 3) c #? 1) a 2) b 3) c #? ^C % _
為什麼會這樣?我的主要問題是 -如何讓它在腳本中工作?!
更新
% bash --version GNU bash, version 4.3.42(1)-release (x86_64-unknown-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc. % uname Linux lx1 2.6.32-642.6.2.el6.x86_64 #1 SMP Mon Oct 24 10:22:33 EDT 2016 x86_64 x86_64 x86_64 GNU/Linux
從手冊:
TMOUT 如果設置為大於零的值,則 TMOUT 被視為內置讀取的預設超時。當輸入來自終端時,如果在 TMOUT 秒後輸入未到達,則選擇命令終止。在互動式 shell 中,該值被解釋為發出主提示後等待輸入的秒數。如果輸入未到達,Bash 在等待該秒數後終止。
所以第一種情況是由於互動式外殼。
$ ps -aef|grep bash; echo "before"; (TMOUT=3; s="no selection"; ps -aef|grep bash; select s in a b c ; do break ; done; echo $s;ps -aef|grep bash);echo "after";ps -aef|grep bash asktyagi 4926 23767 0 09:40 pts/0 00:00:00 grep --color=auto bash asktyagi 23767 23741 0 09:03 pts/0 00:00:00 -bash **before** asktyagi 4927 23767 0 09:40 pts/0 00:00:00 -bash asktyagi 4929 4927 0 09:40 pts/0 00:00:00 grep --color=auto bash asktyagi 23767 23741 0 09:03 pts/0 00:00:00 -bash 1) a 2) b 3) c #? no selection asktyagi 4927 23767 0 09:40 pts/0 00:00:00 -bash asktyagi 4931 4927 0 09:40 pts/0 00:00:00 grep --color=auto bash asktyagi 23767 23741 0 09:03 pts/0 00:00:00 -bash **after** asktyagi 4933 23767 0 09:40 pts/0 00:00:00 grep --color=auto bash asktyagi 23767 23741 0 09:03 pts/0 00:00:00 -bash
現在有腳本
$ cat a.sh #!/bin/bash (TMOUT=3; s="no selection"; select s in a b c ; do break ; done; echo $s) ps -aef|grep bash $ sh a.sh 1) a 2) b 3) c #? no selection asktyagi 5201 5188 0 09:41 pts/0 00:00:00 grep bash asktyagi 23767 23741 0 09:03 pts/0 00:00:00 -bash
使用
timeout
命令。這個例子可以改進,但它說明了這一點。首先使用 bash-builtintrap
命令在退出時執行一些東西,然後執行你的循環。它執行如下:#] timeout 3s sh -c 'trap "echo no selection" EXIT; select s in a b c ; do break ; done; ' 1) a 2) b 3) c #? <waits 3 seconds>no selection