Bash / sh
#!/bin/sh
#!/bin/bash
Startup scripts
- interactive login: /etc/profile (system) -> ~/.bash_profile 或 ~/.profile (先找到的)
- none-interactive login: /etc/bash.bashrc (部分系统) -> ~/.bashrc
- none-interactive login 示例: systemd / init.d 启动脚本环境;其他机器通过 ssh host command 在本机上执行命令;cron job。
通常习惯默认在 ~/.bash_profile 里调用 ~/.bashrc :
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
注意某些系统(如 Ubuntu)默认的 ~/.bashrc 内容直接禁止了 none-interactive login 时运行该脚本内容:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
需要把这行去掉。
Cheatsheet
If
if [ "$INTERFACE" != "pppoe-wan" ]
then
exit
fi
- Operator: =, !=
- Logic operator : -a (and), -o (or)
- number compare : -lt, -gt, -le, -ge, -eq
Check String starts with
word="appel"
if [[ $word = a* ]]
then
echo "Starts with a"
else
echo "No match"
fi
Switch
# This script does a very simple test for checking disk space.
space=`df -h | awk '{print $5}' | grep % | grep -v Use | sort -n | tail -1 | cut -d "%" -f1 -`
case $space in
[1-6]*)
Message="All is quiet."
;;
[7-8]*)
Message="Start thinking about cleaning out some stuff. There's a partition that is $space % full."
;;
9[1-8])
Message="Better hurry with that new disk... One partition is $space % full."
;;
99)
Message="I'm drowning here! There's a partition at $space %!"
;;
*)
Message="I seem to be running with an nonexistent amount of disk space..."
;;
esac
Variables
FOO="${VARIABLE:-default}" # If variable not set or null, use default.
FOO="${VARIABLE:=default}" # If variable not set or null, set it to default.
- "${var%A Suffix}", "${PWD%/}", "${PWD%%/}" : Expand the value contained within the parameter var after removing the string A Suffix from the end of it. Works just like the prefix trimming operation, only takes away from the end.
- ${0%/*} : 当前运行的 bash 脚本($0)所在目录。
- "${var#A Prefix}", "${PWD#/}", "${PWD##/}" : Expand the value contained within the parameter var after removing the string A Prefix from the beginning of it. If the value doesn't have the given prefix, it is expanded as is. The prefix can also be a glob pattern, in which case the string that matches the pattern is removed from the front. You can double the # mark to make the pattern match greedy.
split string
Only available in bash (not sh)
IN="bla@some.com;john@home.com"
arrIN=(${IN//;/ })
echo ${arrIN[1]} # Output: john@home.com
This construction replaces all occurrences of ';' (the initial // means global replace) in the string IN with ' ' (a single space), then interprets the space-delimited string as an array (that's what the surrounding parentheses do).
The syntax used inside of the curly braces to replace each ';' character with a ' ' character is called Parameter Expansion.
There are some common gotchas:
- If the original string has spaces, you will need to use IFS:
IFS=':'; arrIN=($IN); unset IFS; - If the original string has spaces and the delimiter is a new line, you can set IFS with:
IFS=$'\n'; arrIN=($IN); unset IFS;
Tips
Output binary data
# Only work in bash. DO NOT work in sh!
echo -n -e '\x01\x02' > file
fg error "bash:no job control in this shell"
You may need to enable job control:
#! /bin/bash
set -m
cd "pwd" of script self file
参考这里
cd "${0%/*}"
or
SCRIPT_PATH=${0%/*}
if [ "$0" != "$SCRIPT_PATH" ] && [ "$SCRIPT_PATH" != "" ]; then
cd $SCRIPT_PATH
fi