2013-05-27 55 views
1

我一直在嘗試轉換下面的代碼中使用「測試」,而不是「如果」使用多個條件「測試」命令

if [ -e ./blah ] && [ ! -L ./blah ]; 
then 
    exit 1 
fi 

我的本意是用測試來代替,讓我沒有明確地退出1。我想是這樣的:

test -e ./blah && ! -L ./blah; 

,而不是& &,我已經試過-a,用不同的支架的組合,但我沒有成功。我相信應該有一個簡單的方法來做到這一點。誰能幫我 ?

回答

5

test不理解邏輯運算符&&||。您可以使用test -e ./blah -a ! -L ./blah,但如果你使用bash,您還可以切換到它的功能更強大[[ .. ]]結構:

[[ -e ./blah && ! -L ./blah ]] 
1

您可以將它們全部(包括如果再FI):

[[ -e ./blah && ! -L ./blah ]] && exit 1 
1

使用因爲它更強大,所以關鍵字爲[[

if [[ -e ./blah && ! -L ./blah ]] 
    then 
    ... 
fi 

但是,爲了保證便攜性,你可以做這樣的事情太

if [ -e ./blah ] && [ ! -L ./blah ] 
    then 
    ...do something 
fi 
1

至於你問到使用test,你可以做像這樣:

test -e ./blah && test -L ./blah || (echo 'First action' ; echo 'Second action) 

不同的運營商(&&||等)首先由shell解析,所以你不能在命令參數中使用它。

1
if [ -e ./blah ] && [ ! -L ./blah ]; 

相當於

if test -e ./blah && test ! -L ./blah; 

因此可以簡單的寫

test -e ./blah && test ! -L ./blah 

機智:

$ help [\[] | tail -n +3 
[: [ arg... ] 
    Evaluate conditional expression. 

    This is a synonym for the "test" builtin, but the last argument must 
    be a literal `]', to match the opening `['. 
1

執行以下操作:

$ ls -i /bin/test 
54008404 /bin/test 
$ ls -i /bin/[ 
54008404 /bin/test 

54008404inode號碼。這是一個文件的真實名稱。/bin/test只是指向inodeinode包含所有文件的文件信息。

需要注意的是/bin/[/bin/test是相同的inode。這意味着,他們是相同的命令。

因此:

if [ -f "$foo" ] 

相同:

if test -f "$foo" 

if命令執行給出的命令,然後將執行if子句如果該命令將返回真並且不執行該子句如果命令它是假的。

例如:

if grep -q "foo" $foo 
then 
    echo "File $foo contains the regular expression /foo/" 
fi 

完全有效。該grep -q命令(在grep許多變種意味着搜索的正則表達式,如果正則表達式是在該文件中,返回的0退出代碼(這意味着該命令成功,是真實的)。

注有沒有括號。

test命令(或[...])僅僅運行作爲指定的測試,並與0退出代碼(因此該命令是成功),如果測試結果是真回報。這就是它。

你也可以看到這個構造:

[ "$foo" = "$bar" ] && echo "$foo is equal to $bar" 

&&表示如果第一個命令返回退出代碼爲零,則執行下一個命令(並返回退出代碼)。否則,只需返回第一個命令的退出代碼即可。

這樣:

if [ -e ./blah ] && [ ! -L ./blah ]; 

是說跑test -e ./blah,如果這是真的(即,該文件存在)執行test ! -L ./blah,如果這也同樣如此,在運行該語句的if條款。

請注意,[ -e ./blah][ ! -L ./blah ]是兩個獨立的命令。該&&串在一起的兩個命令:

[ "$foo" = "$bar" ] && some_command; 

這是說,運行test "$foo" = "$bar"如果這是真的,運行命令some_command。請注意,這相當於:

if [ "$foo" = "$bar" ] 
then 
    some_command 
fi 

其他列表結構是||。這意味着如果第一個命令成功,則返回0的退出代碼,並且不要運行第二個命令。因此:

[ "$foo" = "$bar" ] || some_command; 

是一樣的:

if [ "$foo" = "$bar" ] 
then 
    : 
else 
    some_command 
fi 

讓我們回到你的_original問題:

if [ -e ./blah ] && [ ! -L ./blah ]; 
then 
    exit 1 
fi 

是一樣的:

if test -e ./blah && test ! -L ./blah 
then 
    exit 1 
fi 

哪個與

0123相同
test -e ./blah && test ! -L ./blah && exit 1 

這意味着:如果test -e ./blah是真(./blah是一個文件),然後&&列表操作後,執行命令。這是test -! -L ./blah。如果此測試也是如此,請在&&列表運算符後再次運行該命令。

test -e ./blah && test -L ./blah || exit 1 

這是說,如果test -e ./blah是真的,運行&&列表操作符之後的命令:

這也可以作爲改寫。如果test -L ./blah爲假,請在||運算符後面運行命令。