專業bash程序設計 Pro Bash Programming - 待遷移



Hello World!

shell腳本是包含一個或多個命令的文件。本章介紹如何建立這樣的文件並使其可執行。還涉及一些shell腳本相關的問題,好比如何命名、放置和執行文件。

本章假設你位於home目錄,你能夠經過以下命令查看:
html

$echo "$HOME"
/home/test

使用pwd命令或PWD變量的當前目錄:
python

$echo "$PWD"
/home/test
$echo "$HOME"
/home/test

若是你是否是在你的home目錄,cd能夠進入:linux

$pwd
/home/backup
$cd
$pwd
/home/test

推薦使用Bash 4.3以上版本,由於它修復了Shellshock漏洞。程序員

代碼

$echo Hello, World!
Hello, World!

文件

文件注意不要有命名衝突,且要放在shell能夠找到的地方。正則表達式

腳本名

初學者常用test做爲腳本名,這樣會和內置命令衝突。用顯示命令類型信息的type命令能夠查看:

redis

$type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /bin/test
test is /usr/bin/test

shell內置命令test用來測試文件類型和比較值,輸入test會執行該內置命令。一般情Unix命令名儘量短。 一個描述性單詞的輔音很或兩個單詞的首部常見(例如mv:move、ls:list、ps:process status、sed:stream
editor)。

咱們的腳本命名爲hw。許多shell程序員添加後綴,如.sh,這個不是必須的。shell

存放目錄

一般在PATH中尋找shell命令:數組

$printf "$PATH"
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/gradle/bin:/home/test/.local/bin:/home/test/bin

也可使用絕對或者相對路徑:安全

/home/test/bin/hw
bin/hw

爲此須要增長目錄bin並在PATH中添加$HOME/binbash

mkdir bin
PATH=$PATH:$HOME/bin

PATH的修改能夠放置在用戶目錄的.bash_profile .bashrc、 .profile等shell啓動時source的文件中,注意只對交互式shell有效,對腳本無效。


建立文件並執行腳本


一般使用文本編輯器來建立程序,咱們這個簡單的腳本使用重定向建立便可:

$echo echo Hello, World! > bin/hw



大於號(>) 告訴shell將命令的輸出發送到指定的文件,而不是終端。運行:

$bash bin/hw
Hello, World!
$sh bin/hw
Hello, World!
$ls -l /bin/sh
lrwxrwxrwx. 1 root root 4 Aug  1  2014 /bin/sh -> bash

能夠見sh是bash的一個符號鏈接。調用sh等於調用bash。

下面添加可執行權限後能夠直接調用腳本。

$chmod +x bin/hw
$hw
Hello, World!
$bin/hw 
Hello, World!
$/home/test/bin/hw
Hello, World!


文本編輯器

可用的工具備vi、e三、nano、emacs、gedit、geany、Wing Ide。我的最喜歡的時後面兩個。效果圖以下:


Wing IDE:

Geany

注意:在Windows的文本文件行結束用回車(CR)和換行(LF)。在Unix系統中只有換行符。Windows的文本編輯器移植到Unix可能須要刪除回車。

完善Hello, World!

#!/bin/bash

#:    Title        :    hw
#:    Date        :    2015-07-18
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    print    Hello,    World!
#:    Options        :    None

printf    "%s\n"    "Hello,    World!"

首行#!/bin/bash表示執行的解釋器。


輸入輸出

參數和變量

位置參數

參數是存儲值的實體,有三種參數:位置參數、特殊參數和變量。位置參數是命令行參數,用數字表示。特殊參數由shell設置,用於存儲狀態相關信息,好比參數數量和最後一個命令的退出碼(好比, *, #, and _)。變量有本身的名字。參數的值可由美圓符號加名字、數值或字符訪問,好比$三、$#或$HOME。能夠添加大括號,好比${10}, ${PWD}或${USER}。

$n:表示第幾個參數,$1 表示第一個參數,$2 表示第二個參數 ...
$0:程序的名稱

Bourne shell只能保存9個位置參數,$10解釋爲${1}0。兼容起見,bash訪問9以上的位置參數必須加大括號,如 ${15}。

shift會使位置參數左移,原來的$0會丟失。

#!/bin/bash
#:    Title        :    hello
#:    Date        :    2015-07-18
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    print    Hello,    World!
#:    Options        :    None
#: Description    :     print Hello and the first command-line argument
printf "%s, %s!\n" "$0" "$1"
printf "%s, %s!\n" "$2" "$3"
shift 
printf "After shift:\n%s, %s!\n" "$2" "$3"

執行結果:

$hello World! 2 3 4
/home/test/bin/hello, World!!
2, 3!
After shift:
3, 4!

特殊參數

$#: 傳遞給程序的總的參數數目
$?: 上一個代碼或者shell程序在shell中退出的狀況,若是正常退出則返回0,反之爲非0值。
$*: 傳遞給程序的全部參數組成的字符串。
$@: 以"參數1" "參數2" ... 形式保存全部參數
$$: 本程序的(進程ID號)PID
$!: 上一個命令的PID
$-: 操做標識

#!/bin/bash
#:    Title        :    hello
#:    Date        :    2015-07-18
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    print    Hello,    World!
#:    Options        :    None
#:  Description    :     print Hello and the first command-line argument
printf "Arguments number: %s\n" "$#" 
printf "Exit code of last command: %s\n" "$?" 
printf "All arguments in string: %s\n" "$*" 
printf "All arguments in list: %s\n" "$@" 
printf "Current process ID: %s\n" "$$" 
printf "Last process ID: %s\n" "$!" 
printf "Flag: %s\n" "$-"

執行結果:

$special_arguments 1 2 3
hello  hw  special_arguments
Arguments number: 3
Exit code of last command: 0
All arguments in string: 1 2 3
All arguments in list: 1
All arguments in list: 2
All arguments in list: 3
Current process ID: 28157
Last process ID: 
Flag: hB

變量標識符的定義和python相似,不作贅述。

name=VALUE



注意:等號的先後不能有空格。shell設置的變量大多爲大寫,好比:HOME、PWD和PATH,但有兩個例外:auto_resume和histchars。

參數和選項

在命令後輸入是參數,他們用空白(一個或多個空格或TAB)分割。引號中或轉移的空白不會有分割做用。
下面的命令都有四個參數:

$echo 1 '2 3' 4 5
1 2 3 4 5
$echo -n Now\ is the time
Now is the time]$printf "%s %s\n" one two three
one two
three

命令行參數有長參數和短參數:

$ echo -n hello
echo -n hello
hello
$ bash --version
bash --version
GNU bash, version 4.2.45(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


數據格式化與輸出

printf FORMAT ARG…



FORMAT中能夠包含普通、轉義和格式化符號。

轉義序列

  • \a:警報(鐘聲)

  • \b:退格

  • \e:Escape字符

  • \f:進紙

  • \n:換行符

  • \r:回車

  • \t:水平製表

  • \v:垂直選項卡

  • \\:反斜槓

  • \nnn:一到三個八進制數字指定的字符

  • \xHH:由一個或兩個十六進制數字指定的字符

格式化符


格式化符前面有百分號。可選修改福可能置於兩個字符之間。參數比格式字符串多時,格式字符串會重用,直到全部的參數消耗完。常見的有%s, %d,%f和%x。

%s表示字符串:

$  printf "%s\n" Print arguments on "separate lines"
Print
arguments
on
separate lines

%b和%s相似,可是會轉義參數。

$  printf "%b\n" "Hello\nworld" "12\tword"
Hello
world
12      word
$  printf "%s\n" "Hello\nworld" "12\tword"
Hello\nworld
12\tword

%d表示整數:

$  printf "%d\n" 23 45 56.78 0xff 011
23
45
bash: printf: 56.78: invalid number
56
255
9

可見整數有十進制、八進制和十六進制兩種表示方法,當參數不是整數時會報錯,可是不會終止執行。

%f表示浮點數,默認保留小數點後六位:

$  printf "%f\n" 12.34 23 56.789 1.2345678
12.340000
23.000000
56.789000
1.234568

%e能夠顯示科學計數法:

$  printf "%e\n" 12.34 23 56.789 123.45678
1.234000e+01
2.300000e+01
5.678900e+01
1.234568e+02

%x和%X分別能夠用大小寫顯示十六進制數據。

$printf "color: #%02x%02x%02x;\n" 65 105 225
color: #4169e1;

寬度指定

在百分號後面添加數值傑克,負數表示左對齊,正數表示右對齊,0則表示用0填充。

$ printf "%8s %-15s:\n" first second third fourth fifth sixth
   first second         :
   third fourth         :
   fifth sixth          :
   
$ printf "%04d\n" 12 23 56 123 255
0012
0023
0056
0123
0255

浮點數的寬度針對字符串表示最大長度,針對浮點則表示小數點位數。

$printf "%12.4s %9.2f\n" John 2 Jackson 4.579 Walter 2.9 hellohellohello 1234567890.9797
        John      2.00
        Jack      4.58
        Walt      2.90
        hell 1234567890.98

        
上例最後一個例子,"hellohellohello"被截斷成4位,浮點數則不會截斷。

下面咱們展現一個銷售報表的實例:

#!/bin/bash
#:    Title        :    Sales Report
#:    Date        :    2015-07-20
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    print formatted sales report
#:    Options        :    None
## Build a long string of equals signs
divider=====================================
divider=$divider$divider
## Format strings for printf
header="\n %-10s %11s %8s %10s\n"
format=" %-10s %11.2f %8d %10.2f\n"
## Width of divider
totalwidth=44
## Print categories
printf "$header" ITEM "PER UNIT" NUM TOTAL
## Print divider to match width of report
printf "%$totalwidth.${totalwidth}s\n" "$divider"
## Print lines of report
printf "$format" \
    Chair 79.95 4 319.8 \
    Table 209.99 1 209.99 \
    Armchair 315.49 2 630.98

    
執行結果:

$sales_report 
 ITEM          PER UNIT      NUM      TOTAL
============================================
 Chair            79.95        4     319.80
 Table           209.99        1     209.99
 Armchair        315.49        2     630.98

 
 注意上例中的${totalwidth},由於後面接了字符s,可能會混淆,因此加上大括號,一般加上大括號是個良好的習慣。  同時和Python同樣,行尾的反斜槓能夠用於續行。

在printf中使用-v參數能夠打印到變量:

$ printf -v num4 "%04d" 4
$ printf "%s\n" "$num4"
0004 

標準輸入/輸出流和重定向

在Unix中一切都是字節流,做爲文件訪問,有三個特殊流不多做爲文件名訪問,即每一個命令有的標準輸入stdin,標準輸出stdout和標準錯誤stderr。文件描述符對應0,1和2。I/O能夠來自或重定向到文件或管道。

文件 文件描述符
輸入文件—標準輸入 標準輸入是文件描述符0。它是命令的輸入,缺省是鍵盤,也能夠是文件或其餘命令的輸出。
輸出文件—標準輸出 標準輸出是文件描述符1。它是命令的輸出,缺省是屏幕,也能夠是文件。
錯誤輸出文件—標準錯誤 標準錯誤是文件描述符2。這是命令錯誤的輸出,缺省是屏幕,一樣也能夠是文件。


重定向用於修改默認的輸入和輸出。使用">"時,若是文件不存在,則建立。若是文件存在,會清空。以下方式能夠清空文件:


$printf "" > FILENAME
$> FILENAME

重定向錯誤:錯誤能夠重定向到標準輸出等。

Command >&m 把標準輸出重定向到文件描述符m中
Command < &- 關閉標準輸入
Command 0>&- 同上
$ printf '%s\n%v\n' OK? Oops! > FILE 2> ERRORFILE
$cat ERRORFILE 
-bash: printf: `v': invalid format character

/dev/null表明空設備文件,沒用的東東均可以往這裏扔。

$printf '%s\n%v\n' OK? Oops! 2>/dev/null
OK?

經過2>&1能夠把錯誤輸出到正常輸出,注意"2>&1"必定要在" > FILE"後面,不然錯誤輸出到屏幕上。

$printf '%s\n%v\n' OK? Oops! > FILE 2>&1

上述代碼bash中有快捷方式:"&> FILE",可是不適用於其餘shell。一樣的有">>",不會清空源文件,也有"&>> FILE"。

excec能夠修改重定向:

exec 1>tempfile
exec 0<datafile
exec 2>errorrfile



輸入重定向小結:

Command < filename > filename2 Command命令以filename文件做爲標準輸入,以filename2文件做爲標準輸出
Command < filename Command命令以filename文件做爲標準輸入
Command << delimiter  從標準輸入中讀入,直接遇到delimiter分界符


輸出重定向小結:

Command > filename 把標準輸出重定向到一個新文件中
Command >> filename 把標準輸出重定向到一個文件中(追加)
Command 1> filename 把標準輸出重定向到一個文件中
Command > filename 2>&1 把標準輸出和錯誤一塊兒重定向到一個文件中
Command 2 > filename 把標準錯誤重定向到一個文件中
Command 2 >> filename 把標準輸出重定向到一個文件中(追加)
Command >> filename2>&1 把標準輸出和錯誤一塊兒重定向到一個文件(追加)

讀取輸入


read是讀取標準輸入的內置命令。默認狀況下,它讀取直到換行符。輸入存儲一個或多個變量。

read var

若是有一個以上的變量,第一個字分配給第一變量,第二個字被分配給第二個變量,以此類推,最後一個變量接收全部剩餘字:

$ read a b c d
January February March April May June July August
$  echo $a
bash: $: command not found...
$ echo $a
January
$ echo $b
February
$ echo $c
March
$ echo $d
April May June July August
$printf "%s\n" "$d"
April May June July August


讀bash的版本有幾個選項。只有-r選項POSIX標準被承認,表示不轉義。

$read b
\\  
$echo $b
\
$read -r a
\\
$echo $a
\\

重定向至文件:

read var <  FILENAME



管道

管道(Pipeline)是原始的軟件管道:便是一個由標準輸入輸出連接起來的進程集合,上一個進程的輸出(stdout)直接做爲下一個進程的輸入(stdin)。bash用"|"表示管道。

$  printf "%s\n" "$RANDOM" "$RANDOM" "$RANDOM" "$RANDOM" | tee FILENAME
23173
30110
30212
3056
$  cat FILENAME
23173
30110
30212
3056

tee命令讀取標準輸入並將其傳遞到一個或多個文件到標準輸出, 另有-a參數表示追加到文件末尾。 $RANDOM是返回0-32,767之間的整數的bash變量。


命令替換


命令替換:容許你使用命令的標準輸出就好像它是一個變量值同樣。其語法爲:$(UNIX command)。另外有種遺留語法,使用反引號(`,又名重音符)

#!/bin/bash
#:    Title        :    Command Substitution
#:    Date        :    2015-07-18
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    print    Hello,    World!
#:    Options        :    None
#:  Description    :     print Hello and the first command-line argument
printf "`date`\n"
printf "$( date )\n"

執行結果:

$ cmd_sbst 
Sat Jul 18 16:41:34 CST 2015
Sat Jul 18 16:41:34 CST 2015


循環和分支



在shell中,有三種類型的循環(while,    until和for)和三種條件執行(if,    case和控制操做符&&    and    ||,即AND和OR)。


退出狀態

上一命令執行成功時,$?返回0,不然爲1到255之間的正整數,失敗的命令一般返回1。

$ echo $?
1
$ mkdir /qwerty
mkdir: 沒法建立目錄"/qwerty": 文件已存在
$ echo $?
1

測試表達式

測試表達式有test命令和非標準的關鍵字:[[ 和 ((。test命令比較字符串、整數和各類文件屬性; ((測試算術表達式,[[和((相似且增長了正則表達式比較。注意括號和其餘字符之間必定要有空格。


test命令

單箇中括號對和test是等價的。

文件測試:

-e 文件名:若是文件存在則爲真,另有非標準參數-a實現相似功能。
-r 文件名:若是文件存在且可讀則爲真
-w 文件名:若是文件存在且可寫則爲真
-x 文件名:若是文件存在且可執行則爲真
-s 文件名:若是文件存在且不爲空
-d 文件名:若是文件存在且爲目錄則爲真
-f 文件名:若是文件存在且爲普通文件則爲真
-c 文件名:若是文件存在且爲字符型特殊文件則爲真
-b 文件名:若是文件存在且爲塊特殊文件則爲真
-h -L 文件名:若是文件存在且爲塊特殊文件則爲真


$ test -h /etc/rc.local
$ echo $?
1
$ test -h hello 
$ echo $?
0
$ [ -x "$HOME/bin/hw" ]
$ echo $?
0
$ [[ -s $HOME/bin/hw ]]
$ echo $?
0
$ [ -s $HOME/bin/hw ]
$ echo $?
0
整數測試

-eq:等於則爲真
-ne:不等於則爲真
-gt:大於則爲真
-ge:大於等於則爲真
-lt:小於則爲真
-le:小於等於則爲真

test 1 -eq 1
$ echo $?
0
$ [ 2 -eq 1 ]
$ echo $?
1
$ [ 2 -ne 1 ]
$ echo $?
0


字符串測試


  = 等於則爲真。這個地方比較怪異,其餘語言都是==表示判斷是否相等,bash也支持==,可是竟然不是標準用法。

  != 不相等則爲真。

  -z字串 字串長度僞則爲真。

  -n字串 字串長度不僞則爲真。

$a=1
$b=1
$test "$a" = "$b"
$echo $?
0
$[ "$a" != "$b" ]
$echo $?
1
$ [ -z "" ]
$ echo $?
0
$ test -n ""
$ echo $?
1
$ str1=abc
$ str2=def
$ test "$str1" \< "$str2"
$ echo $?
0
$ test "$str1" \> "$str2"
$ echo $?
1

注意大於和小於符號因爲和重定向有衝突,須要轉義。


[[...]]:計算表達式


[[...]]和test相似,有所加強。但不是內置命令,參數可擴展,但不執行分詞和文件擴展名,且不是標準的,建議儘可能使用test。

加強:使用=~能夠匹配正則表達式;支持&&和||。

# string=whatever
# [[ $string =~ h[aeiou] ]]
#echo $?
0
# [[ $string =~ h[aeiou]i ]]
#echo $?
1


(( … )):評估算術表達式



非標準特徵。若是算術表達式求值爲零返回true,不然返回真。和以下方式等價:

test $(( a - 2 )) -ne 0
[ $a != 0 ]

使用shell語法,而不是內置的命令,大於和小於不須要轉義。好比:

if (( total > max )); then : ...; fi
    ((verbose)) && command ## execute command if verbose != 0


非數值當作0來處理。

$y=yes
$((y)) && echo $y || echo n
n


條件執行



if

語法:

if <condition list>
then
<list>
fi


若是<condition list>爲 true則執行<list>。
執行<條件列表>成功:


#!/bin/bash
#:    Title        :    Read Check
#:    Date        :    2015-07-25
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    Read and Check Input 
#:    Options        :    None
read name
if [[ -z $name ]]
then
    echo "No name entered" >&2
    exit 1 ## Set a failed return code
fi

執行結果:

$read_check 
No name entered
$read_check 
test

else能夠在爲false的時候執行:

#!/bin/bash
#:    Title        :    Integer Check
#:    Date        :    2015-07-25
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    Integer Check
#:    Options        :    None
printf "Enter a number not greater than 10: "
read number
if (( number > 10 ))
then
    printf "%d is too big\n" "$number" >&2
    exit 1
else
    printf "You entered %d\n" "$number"
fi

執行結果:

$integer_check 
Enter a number not greater than 10: 11
11 is too big
$integer_check 
Enter a number not greater than 10: 3
You entered 3

多個條件判斷可使用elif:

#!/bin/bash
#:    Title        :    multi if
#:    Date        :    2015-07-25
#:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
#:    Version        :    1.0
#:    Description    :    Demo elif
#:    Options        :    None
printf "Enter a number between 10 and 20 inclusive: "
read number
if (( number < 10 ))
then
    printf "%d is too low\n" "$number" >&2
    exit 1
elif (( number > 20 ))
then
    printf "%d is too high\n" "$number" >&2
    exit 1
else
    printf "You entered %d\n" "$number"
fi

執行結果

$if3 
Enter a number between 10 and 20 inclusive: 3
3 is too low 
$if3 
Enter a number between 10 and 20 inclusive: 23 
23 is too high 
$if3 
Enter a number between 10 and 20 inclusive: 
20 You entered 20


條件操做符:&&和||



AND和OR的執行順序從左至右。若是前面的命令成功就會執行AND後面部分。若是前面部分部分執行失敗就會執行OR後面部分。

&&的應用實例:若是目錄存在就進入。

test -d "bin" && cd "bin"

||的應用實例:若是目錄不存在就返回1退出。

$cd "bin" || exit 1
-bash: cd: bin: No such file or directory
logout

更多組合實例:

mkdir "$HOME/bin" && cd "$HOME/bin" || exit 1
if [ -d "$dir" ] && cd "$dir"
then
    echo "$PWD"
fi

case

case
case語句針對單詞(一般是變量)選擇模式並執行該模式相關聯的命令。模式中可使用通配符模式(*和)和字符列表和區間([...])。

語法:

case $1 in
    *"$2"*) true ;;
    *) false ;;
esac

一個常見實例是肯定字符串是否包含在另外一個字符串中。它比用grep快,由於grep須要建立新的進程:

case $1 in
    *"$2"*) true ;;
    *) false ;;
esac


另外一常見的任務是檢查字符串是不是有效的數字。

case $1 in
    *[!0-9]*) false;;
    *) true ;;
esac

也能夠用於參數檢查:

case $# in
    3) ;; ## We need 3 args, so do nothing
    *) printf "%s\n" "Please provide three names" >&2
        exit 1
        ;;
esac

循環


 
shell提供三種類型的循環:while, until和for。
 

while


語法:

while <list>
 do
     <list>
 done

 
實例:
 

#!/bin/bash
   
 #:    Title        :    Simple While
 #:    Date        :    2015-07-27
 #:    Author        :    "Xu.Rongzhong"    <xurongzhong#126.com>
 #:    Version        :    1.0
 #:    Description    :    Simple While with incrementing a variable
 #:    Options        :    None
   
 n=1
 while [ $n -le 10 ]
 do
     echo "$n"
     n=$(( $n + 1 ))
 done

 
執行結果:
 

$while1
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

 
true能夠用來建立無限循環:
 

while true ## ':' can be used in place of true
 do
     read x
 done

 
while能夠逐行讀取數據:
 

while IFS= read -r line
 do
     : do something with "$line"
 done < FILENAME?


until

   
 
不多使用,循環到條件失敗,和while相反:

n=1
until [ $n -gt 10 ]
do
    echo "$n"
    n=$(( $n + 1 ))
done
 


for

     
迭代模式:

for var in Canada USA Mexico
do
    printf "%s\n" "$var"
done
 
另有非標準C語言格式:
 
for (( n=1; n<=10; ++n ))
do
    echo "$n"
done
 

break

 
用於退出循環
 
while :
do
    read x
    [ -z "$x" ] && break
done
 
後面加數字還能夠跳出多級循環,好比:
 
for n in a b c d e
    do
    while true
    do
        if [ $RANDOM -gt 20000 ]
        then
            printf .
            break 2 ## break out of both while and for loops
        elif [ $RANDOM -lt 10000 ]
        then
            printf '"'
            break ## break out of the while loop
        fi
    done
done
echo
 


continue

退出當次循環
for n in {1..9} ## See Brace expansion in Chapter 4
do
    x=$RANDOM
    [ $x -le 20000 ] && continue
    echo "n=$n x=$x"
done
 


魔線科技(深圳)有限公司測試部 shell培訓教程

公司大量招收測試人員,1-3年經驗,正規統招本科學歷,英語四級, 具有測試基礎,有python或linux簡單使用經驗優先,薪水:5-15k 本科如下特別優秀者能夠考慮 簡歷接收:xu.rongzhong#moxiangroup.com. 方向:互聯網後臺測試、自動化測試、性能測試、安全測試等。

相關文章
相關標籤/搜索