踩踩Linux命令中的那些坑

有時候面對命令的執行和條件的判斷,可能會遇到莫名奇妙的原因,可能是人為錯誤導致,也可能是命令本身的問題。

expr的坑

expr 是用來對數值進行計算的命令,命令的前后參數需要用空格隔開

[root@localhost ~]# whatis expr
expr (1) – evaluate expressions ? ?表達式求值

expr命令被用做表達式求職計算,但是 expr計算的結果為0的時候,將會被認為是錯誤的,不能作為條件判斷的依據

例如:

[root@localhost ~]# expr 1 + 2

3

expr還可以對變量的值進行計算

[root@localhost ~]# n=3;expr $n + 2

5

但命令執行后是否成功呢??

$? 是shell中顯示命令執行結果是否正確的內置變量,如果執行結果的值為0,表示命令正確執行

使用一個未定義的變量試試

[root@localhost ~]# expr $x + 2;echo $?

2

0

坑!

#結果是對的

[root@localhost ~]# expr $y + 0

0

#被判定為命令執行失敗

[root@localhost ~]# echo $?

1

[root@localhost ~]# y=10;expr $y + 0

10

[root@localhost ~]# echo $?

0

原因

expr的執行結果如果是0,將會被 $? 認為命令執行失敗。expr不能輕易用于作為條件判斷,有時候不能當做條件判斷的依據

在expr命令的幫助文檔中有一句描述:Exit ?status ?is ?0 ?if ?EXPRESSION ?is ?neither null nor 0, 1 if EXPRESSION is null or 0, 2 if?EXPRESSION is syntactically invalid, and 3 if an error occurred.

也就是說,如果表達式的執行結果為null或者0,就認為執行的最終結果為1[命令執行失敗],否則為0[命令執行成功]

類似的情況

let的坑

[root@localhost ~]# i=0;let i++;echo $?

1

[root@localhost ~]# i=0;let ++i;echo $?

0

[root@localhost ~]# let m=0;echo $?

1

查一下let的幫助

help let

和expr類似的情況

Exit Status:If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.

[root@localhost ~]# i=10;j=-10;

[root@localhost ~]# let sum=i+j

執行結果是對的,但被判定為執行命令失敗

[root@localhost ~]# echo $sum

0

[root@localhost ~]# echo $?

1

 

例如想計算出兩個數的值就輸出,則會出現不能成功輸出計算得出值得情況,就是因為前一條命令被判定為執行失敗,使用短路與的命令,后續不執行導致的,所以,只能把一條命令拆成2條命令去寫

[root@localhost ~]# let sum=i+j && echo $sum

[root@localhost ~]# let sum=i+j ;echo $sum

0

用于條件判斷的命令如果不嚴謹,將會導致一些無法預料的事情發生!

 

在做變量測試時候遇到的另一個坑

test命令

  • 長格式的例子:

test “$A” == “$B” && echo “Strings are equal”

test “$A” -eq?“$B” && echo “Integers are equal”

  • 簡寫格式的例子:

[ “$A” == ?“$B” ] && echo “Strings are equal”

[ “$A” -eq “$B” ] && echo “Integers are equal”

[root@localhost ~]# whatis test

test (1) ????????????– check file types and compare values ? ? ? ?檢查文件類型和值進行比較

[root@localhost ~]# help test

test: test [expr]

Evaluate conditional expression.

其中有一個參數

-n STRING
STRING True if string is not empty. ? ? ? ?如果字符串不為空表示為真

 

test的坑

測試成功返回0.測試失敗返回255以內的數

[$name 是一個不存在的變量]

[root@localhost ~]# [ -n $name ]? ? ? ? ? ? 為空的變量測試為真???what??

[root@localhost ~]# echo $?

0? ? ? ? ? ?竟然 測試成功

[root@localhost ~]# echo $name ? ? ? ? ? ?$name沒有值

 

[root@localhost ~]# name=wang? ? ? ? ? ? 給$name 賦值

[root@localhost ~]# [ -n $name ]? ? ? ? ? ? 測試[如果變量不為空則為true]

[root@localhost ~]# echo $?

0? ? ? ? ? ? OK,沒問題

[root@localhost ~]# unset name? ? ? ? ? ? 刪除$name變量,此時$name的值為空,測試時應該表現為假才對

[root@localhost ~]# [ -n $name ]? ? ? ? ? ? ???不對了

[root@localhost ~]# echo $?

0? ? ? ? ? ? 刪除變量$name后,此時測試應該表現為失敗,返回其他數字

[root@localhost ~]# test -n $name;echo $?

0

[root@localhost ~]# [[ -n $name ]]

[root@localhost ~]# echo $?

1

[root@localhost ~]# echo $name

#由于之前已經刪掉了$name變量的值,所以已經為空,不為空表示為真,為空表現為假,所以一下的測試都是失敗的

[root@localhost ~]# [ -n “$name”?]? ? ? ? ? ? 加上雙引號進行測試

[root@localhost ~]# echo $?

1 ? ? ? ? ? 由于已經unset掉了$name,所以測試的語句的返回值是其他數,這里是對的

[root@localhost ~]# test -n “$name” ? ? ? ? ? ?加上引號測試變量

[root@localhost ~]# echo $?

1? ? ? ? ? ? 由于已經unset掉了$name,所以測試的語句的返回值是其他數,這里是對的

 

不加引號,判斷出來全是真,這是一個坑!坑!坑!

 

 

本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/88818

(0)
無言勝千言無言勝千言
上一篇 2017-11-22
下一篇 2017-11-23

相關推薦

  • sed文本處理器

    文本處理三劍客之一

    Linux干貨 2017-12-10
  • IP地址之IPv6

    一、IPv6概述   目前使用的IP地址都是IPv4版本,之所以開發出IPv6版本主要是基于以下原因:     1、IPv4地址空間不足,分配不合理;     2、IPv4頭部太過于復雜;     3、使用IPv4使得路由器及主機配置復雜;     4、對于IPv4重新…

    Linux干貨 2016-01-13
  • linux基礎學習-網絡基礎

    一、OSI七層模型 二、TCP/IP模型         三次握手原理 三、常見服務的默認端口 四、IP地址、子網劃分基礎知識     通信原理:一般數據的交互產生是在應用層(TCP/IP模型),應用層以下可以看成是搬運工,不同層的協議定義了不同的搬運工的工作內容,直到最后,把數…

    Linux干貨 2016-09-05
  • 批量部署lxc虛擬機

    前言:lxc是一種操作系統層虛擬化(Operating system–level virtualization)技術,為Linux內核容器功能的一個用戶空間接口。它將應用軟件系統打包成一個軟件容器(Container),內含應用軟件本身的代碼,以及所需要的操作系統核心和庫。通過統一的命名空間和共用API來分配不同軟件容器的可用硬件資源,創造出應用程…

    Linux干貨 2016-03-20
  • 關于文件查找和解壓縮

                     文件查找和解壓縮在文件系統上查找符合條件的文件,文件查找的工具有兩個,locate 和find文件查找分為:          &nbs…

    系統運維 2016-08-18
  • Shell編程之select循環&函數詳解

    一、select循環        功能:主要用于創建菜單,菜單按數字順序排列。并將PS3變量的值用作用戶輸入提示。用戶的選擇被保存在內置變量REPLY中。也可以和case語句結合,在select循環中對用戶的輸入作出判斷并處理。      &nbs…

    Linux干貨 2016-08-21
欧美性久久久久