源代碼下載:?LearnBash-cn.sh
Bash 是一個(gè)為 GNU 計(jì)劃編寫(xiě)的 Unix shell,是 Linux 和 Mac OS X 下的默認(rèn) shell。 以下大多數(shù)例子可以作為腳本的一部分運(yùn)行,也可直接在 shell 下交互執(zhí)行。
#!/bin/bash
# 腳本的第一行叫 shebang,用來(lái)告知系統(tǒng)如何執(zhí)行該腳本:
# 參見(jiàn): http://en.wikipedia.org/wiki/Shebang_(Unix)
# 如你所見(jiàn),注釋以 # 開(kāi)頭,shebang 也是注釋。
# 顯示 “Hello world!”
echo Hello world!
# 每一句指令以換行或分號(hào)隔開(kāi):
echo 'This is the first line'; echo 'This is the second line'
# 聲明一個(gè)變量:
Variable="Some string"
# 下面是錯(cuò)誤的做法:
Variable = "Some string"
# Bash 會(huì)把 Variable 當(dāng)做一個(gè)指令,由于找不到該指令,因此這里會(huì)報(bào)錯(cuò)。
# 也不可以這樣:
Variable= 'Some string'
# Bash 會(huì)認(rèn)為 'Some string' 是一條指令,由于找不到該指令,這里再次報(bào)錯(cuò)。
# (這個(gè)例子中 'Variable=' 這部分會(huì)被當(dāng)作僅對(duì) 'Some string' 起作用的賦值。)
# 使用變量:
echo $Variable
echo "$Variable"
echo '$Variable'
# 當(dāng)你賦值 (assign) 、導(dǎo)出 (export),或者以其他方式使用變量時(shí),變量名前不加 $。
# 如果要使用變量的值, 則要加 $。
# 注意: ' (單引號(hào)) 不會(huì)展開(kāi)變量(即會(huì)屏蔽掉變量)。
# 在變量?jī)?nèi)部進(jìn)行字符串代換
echo ${Variable/Some/A}
# 會(huì)把 Variable 中首次出現(xiàn)的 "some" 替換成 “A”。
# 變量的截取
Length=7
echo ${Variable:0:Length}
# 這樣會(huì)僅返回變量值的前7個(gè)字符
# 變量的默認(rèn)值
echo ${Foo:-"DefaultValueIfFooIsMissingOrEmpty"}
# 對(duì) null (Foo=) 和空串 (Foo="") 起作用; 零(Foo=0)時(shí)返回0
# 注意這僅返回默認(rèn)值而不是改變變量的值
# 內(nèi)置變量:
# 下面的內(nèi)置變量很有用
echo "Last program return value: $?"
echo "Script's PID: $$"
echo "Number of arguments: $#"
echo "Scripts arguments: $@"
echo "Scripts arguments separated in different variables: $1 $2..."
# 讀取輸入:
echo "What's your name?"
read Name # 這里不需要聲明新變量
echo Hello, $Name!
# 通常的 if 結(jié)構(gòu)看起來(lái)像這樣:
# 'man test' 可查看更多的信息
if [ $Name -ne $USER ]
then
echo "Your name isn't your username"
else
echo "Your name is your username"
fi
# 根據(jù)上一個(gè)指令執(zhí)行結(jié)果決定是否執(zhí)行下一個(gè)指令
echo "Always executed" || echo "Only executed if first command fails"
echo "Always executed" && echo "Only executed if first command does NOT fail"
# 在 if 語(yǔ)句中使用 && 和 || 需要多對(duì)方括號(hào)
if [ $Name == "Steve" ] && [ $Age -eq 15 ]
then
echo "This will run if $Name is Steve AND $Age is 15."
fi
if [ $Name == "Daniya" ] || [ $Name == "Zach" ]
then
echo "This will run if $Name is Daniya OR Zach."
fi
# 表達(dá)式的格式如下:
echo $(( 10 + 5 ))
# 與其他編程語(yǔ)言不同的是,bash 運(yùn)行時(shí)依賴(lài)上下文。比如,使用 ls 時(shí),列出當(dāng)前目錄。
ls
# 指令可以帶有選項(xiàng):
ls -l # 列出文件和目錄的詳細(xì)信息
# 前一個(gè)指令的輸出可以當(dāng)作后一個(gè)指令的輸入。grep 用來(lái)匹配字符串。
# 用下面的指令列出當(dāng)前目錄下所有的 txt 文件:
ls -l | grep "\.txt"
# 重定向輸入和輸出(標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤)。
# 以 ^EOF$ 作為結(jié)束標(biāo)記從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)并覆蓋 hello.py :
cat > hello.py << EOF
#!/usr/bin/env python
from __future__ import print_function
import sys
print("#stdout", file=sys.stdout)
print("#stderr", file=sys.stderr)
for line in sys.stdin:
print(line, file=sys.stdout)
EOF
# 重定向可以到輸出,輸入和錯(cuò)誤輸出。
python hello.py < "input.in"
python hello.py > "output.out"
python hello.py 2> "error.err"
python hello.py > "output-and-error.log" 2>&1
python hello.py > /dev/null 2>&1
# > 會(huì)覆蓋已存在的文件, >> 會(huì)以累加的方式輸出文件中。
python hello.py >> "output.out" 2>> "error.err"
# 覆蓋 output.out , 追加 error.err 并統(tǒng)計(jì)行數(shù)
info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err
wc -l output.out error.err
# 運(yùn)行指令并打印文件描述符 (比如 /dev/fd/123)
# 具體可查看: man fd
echo <(echo "#helloworld")
# 以 "#helloworld" 覆蓋 output.out:
cat > output.out <(echo "#helloworld")
echo "#helloworld" > output.out
echo "#helloworld" | cat > output.out
echo "#helloworld" | tee output.out >/dev/null
# 清理臨時(shí)文件并顯示詳情(增加 '-i' 選項(xiàng)啟用交互模式)
rm -v output.out error.err output-and-error.log
# 一個(gè)指令可用 $( ) 嵌套在另一個(gè)指令內(nèi)部:
# 以下的指令會(huì)打印當(dāng)前目錄下的目錄和文件總數(shù)
echo "There are $(ls | wc -l) items here."
# 反引號(hào) `` 起相同作用,但不允許嵌套
# 優(yōu)先使用 $( ).
echo "There are `ls | wc -l` items here."
# Bash 的 case 語(yǔ)句與 Java 和 C++ 中的 switch 語(yǔ)句類(lèi)似:
case "$Variable" in
# 列出需要匹配的字符串
0) echo "There is a zero.";;
1) echo "There is a one.";;
*) echo "It is not null.";;
esac
# 循環(huán)遍歷給定的參數(shù)序列:
# 變量$Variable 的值會(huì)被打印 3 次。
for Variable in {1..3}
do
echo "$Variable"
done
# 或傳統(tǒng)的 “for循環(huán)” :
for ((a=1; a <= 3; a++))
do
echo $a
done
# 也可以用于文件
# 用 cat 輸出 file1 和 file2 內(nèi)容
for Variable in file1 file2
do
cat "$Variable"
done
# 或作用于其他命令的輸出
# 對(duì) ls 輸出的文件執(zhí)行 cat 指令。
for Output in $(ls)
do
cat "$Output"
done
# while 循環(huán):
while [ true ]
do
echo "loop body here..."
break
done
# 你也可以使用函數(shù)
# 定義函數(shù):
function foo ()
{
echo "Arguments work just like script arguments: $@"
echo "And: $1 $2..."
echo "This is a function"
return 0
}
# 更簡(jiǎn)單的方法
bar ()
{
echo "Another way to declare functions!"
return 0
}
# 調(diào)用函數(shù)
foo "My name is" $Name
# 有很多有用的指令需要學(xué)習(xí):
# 打印 file.txt 的最后 10 行
tail -n 10 file.txt
# 打印 file.txt 的前 10 行
head -n 10 file.txt
# 將 file.txt 按行排序
sort file.txt
# 報(bào)告或忽略重復(fù)的行,用選項(xiàng) -d 打印重復(fù)的行
uniq -d file.txt
# 打印每行中 ',' 之前內(nèi)容
cut -d ',' -f 1 file.txt
# 將 file.txt 文件所有 'okay' 替換為 'great', (兼容正則表達(dá)式)
sed -i 's/okay/great/g' file.txt
# 將 file.txt 中匹配正則的行打印到標(biāo)準(zhǔn)輸出
# 這里打印以 "foo" 開(kāi)頭, "bar" 結(jié)尾的行
grep "^foo.*bar$" file.txt
# 使用選項(xiàng) "-c" 統(tǒng)計(jì)行數(shù)
grep -c "^foo.*bar$" file.txt
# 如果只是要按字面形式搜索字符串而不是按正則表達(dá)式,使用 fgrep (或 grep -F)
fgrep "^foo.*bar$" file.txt
# 以 bash 內(nèi)建的 'help' 指令閱讀 Bash 自帶文檔:
help
help help
help for
help return
help source
help .
# 用 mam 指令閱讀相關(guān)的 Bash 手冊(cè)
apropos bash
man 1 bash
man bash
# 用 info 指令查閱命令的 info 文檔 (info 中按 ? 顯示幫助信息)
apropos info | grep '^info.*('
man info
info info
info 5 info
# 閱讀 Bash 的 info 文檔:
info bash
info bash 'Bash Features'
info bash 6
info --apropos bash
更多建議: