Bash tips
Shell Style Guide
https://google.github.io/styleguide/shellguide.html
变量相加
$((a + b))
数组长度
${#array}
String replace
${string/pattern/new}
replace${string//pattern/new}
replace all
message='The secret code is 12345'
echo ${message/[0-9]/X}
# The secret code is X2345
echo ${message//[0-9]/X}
# The secret code is XXXXX
获取文件列表
files=$(ls /path/to/*.txt)
echo $files
for f in $files
do
echo $f
done
Single quotes / double quotes
Single quotes won't interpolate anything, but double quotes will. For example, variables, expressions, backticks, certain \
escapes, etc.
Example
echo "$(echo "upg")"
# upg
echo '$(echo "upg")'
# $(echo "upg")
difference-between-single-and-double-quotes-in-bash
function
# $1, $2, ... $n, ..., $#
greeting() {
echo "Hello $1"
}
greeting "Joe"
result="$(greeting 'Joe')"
Check if a file or directory exists
使用条件判断和 -f
参数或 -d
参数
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
FILE=/ect/resolve.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
else
echo "$FILE does not exist"
fi
FILE=/etc/docker
if [ -d "$FILE" ]; then
echo "$FILE is a directory"
fi
How to Check if a File or Directory Exists in Bash | Linuxize
判断字符串为空(string is null or empty)
status=`git status | grep commit`
if [ ! -z "$status" ]; then
echo 'is not empty'
else
echo 'is empty'
fi
比较字符串
-
[ string1 = string2 ]
: equal in[]
-
[[ string1 == string2 ]]
: equal in[[]]
-
string1 != string2
: not equal -
string1 =~ regex
: regex match -
-z string1
: zero length -
-n string1
: not zero length
a="Linux"
b="macos"
if [[ $a == $b ]]; then
echo "Strings are equal."
else
echo "Strings are not equal."
fi
if [[ $a =~ .*nux.* ]]; then
echo "It's there"
fi
for 循环
projects=(p1 p2)
for i in "${projects[@]}"; do
echo $i '-'
done
Local variable / environment variable
# Only in current shell
name=demo
# Can be accessed by process.env.NODE_ENV in script
export NODE_ENV=production
${}, $()
-
${var}
: 获取并代入变量的值 -
$(command)
: 执行命令并返回结果 -
`command`
: 执行命令并返回结果
Bash function
所有变量(包括函数内)默认是全局变量,除非在函数内用local
声明。
#!/bin/bash
greeting () {
echo "Hello $1"
}
greeting "Joe"
cd to the path of the script
cd "$(dirname "$0")"
获取 bash 脚本的 arguments
bash 函数通过这种方式拿到的是本身的参数。
copy.sh -from a.file -to b.file
$# # 4, total number
$0 # copy.sh, script file name
$1 # -from
$2 # a.file
$3 # -to
$4 # b.file
检查是否传递了参数
# 没有传递任何参数
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
# 没有传递第一个参数
if [ -z "$1" ]
then
echo "No argument supplied"
fi
bash: Get OS type
if [[ "$OSTYPE" == "linux-gnu" ]]; then
# ...
elif [[ "$OSTYPE" == "darwin"* ]]; then
# ...
fi
os detection - How to detect the OS from a Bash script? - Stack Overflow
zsh tips
You have new mail.
mail
type number ID to read; d 1-9
to delete; x/q
to leave.
cd to history
cd -
cd -2
cd -3
cd -<tab>
Bash 批量文件重命名
-
Single file
mv [option] source destination mv file1.txt file2.txt
-
Multiple files with
sed
regexpfiles="*.wav" for f in $files; do newname=`echo "$f" | sed 's/[0-9]*//g'` mv "$f" "$newname" done
-
Multiple files
for f in *.html; do mv "$f" "${f%.html}.pug" done
${f%.html}
is using the Shell parameter expansion.${f%.html} 匹配末尾, ${f#../ouptput} 匹配开头
-
Multiple files with
find
find . -type f -name "*.html" -exec sh -c 'f="{}"; mv -- "$f" "${f%.html}.pug"' \;
Bash 支持换行符
printf 更通用
printf "hello\nworld"
echo 在不同环境不同版本可能不一致
echo 'Hello\nworld'
echo -e "Hello\nworld"
echo $'Hello\nworld'
出错立即退出脚本
默认情况下 shell 一条命令出错后仍会执行下面的命令,可以通过设置,在出错后立即退出脚本
set -e
# commands which fail will cause the script to exit immediately
bash -e my_script.sh