知乎專欄 | 多維度架構 | 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者” |
# chsh --list /bin/sh /bin/bash /sbin/nologin /bin/tcsh /bin/csh /bin/ksh # chsh --list-shells /bin/sh /bin/bash /sbin/nologin /bin/dash /bin/zsh
$ chsh -s /bin/zsh or $ usermod -s /bin/zsh
show me current shell
neo@netkiller:~$ echo $SHELL /bin/zsh neo@netkiller:~$ cat /etc/passwd|grep neo neo:x:1000:1000:Neo Chen,,,:/home/neo:/bin/zsh
判斷當前用戶是否為root
#!/bin/bash if [[ $EUID -ne 0 ]]; then echo "This script must be run as root" exit 1 fi
使用 #!/bin/su 可以切換當前shell的所有者,全局切換
# cat test.sh #!/bin/su www ls
局部切換,運行$PROG後將pid(進程ID)寫入$PIDFILE檔案
su - $USER -c "$PROG & echo \$! > $PIDFILE"
cat <<End-of-message 8 ------------------------------------- 9 This is line 1 of the message. 10 This is line 2 of the message. 11 This is line 3 of the message. 12 This is line 4 of the message. 13 This is the last line of the message. 14 ------------------------------------- End-of-message
MYSQL=mysql MYSQLOPTS="-h $zs_host -u $zs_user -p$zs_pass $zs_db" $MYSQL $MYSQLOPTS <<SQL SELECT category.cat_id AS cat_id , category.cat_name AS cat_name , category.cat_desc AS cat_desc , category.parent_id AS parent_id , category.sort_order AS sort_order , category.measure_unit AS measure_unit , category.style AS style , category.is_show AS is_show , category.grade AS grade FROM category SQL
<<-LimitString可以抑制輸出時前邊的tab(不是空格). 這可以增加一個腳本的可讀性.
cat <<-ENDOFMESSAGE This is line 1 of the message. This is line 2 of the message. This is line 3 of the message. This is line 4 of the message. This is the last line of the message. ENDOFMESSAGE
關閉參數替換
NAME="John Doe" RESPONDENT="the author of this fine script" cat <<'Endofmessage' Hello, there, $NAME. Greetings to you, $NAME, from $RESPONDENT. Endofmessage
NAME="John Doe" RESPONDENT="the author of this fine script" cat <<\Endofmessage Hello, there, $NAME. Greetings to you, $NAME, from $RESPONDENT. Endofmessage
your_shell 2>&1
錯誤輸出演示
[root@localhost ~]# id ethereum id: ethereum: no such user # 這裡可以看到錯誤輸出 id: ethereum: no such user [root@localhost ~]# id ethereum > test id: ethereum: no such user 我們嘗試將他重定向到檔案 test,但是結果仍是輸出 id: ethereum: no such user [root@localhost ~]# cat test [root@localhost ~]# 查看 test 檔案,內容空。
繼續做實驗
[root@localhost ~]# id ethereum > test 2>&1 [root@localhost ~]# cat test id: ethereum: no such user
測試實驗結果成功了,將錯誤輸出轉到標準輸出,然後寫入檔案。
echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward;
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://du8c1in9.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
cat << EOF > foo.sh printf "%s was here" "$name" EOF cat >> foo.sh <<EOF printf "%s was here" "$name" EOF
create a pipes
$ mkfifo /tmp/pipe $ mkfifo -m 0644 /tmp/pipe $ mknod /tmp/pipe p
let's see it
$ ls -l /tmp/piple prw-r--r-- 1 neo neo 0 2009-03-13 14:40 /tmp/piple
remove a pipes
rm /tmp/pipe
using it
standing by pipe
$ cat /tmp/pipe
push string to pipe
$ echo hello world > /tmp/pipe
fetch string from /tmp/pipe
$ cat /tmp/piple hello world
# mktemp /tmp/tmp.p8p0v5YzPf # mktemp /tmp/test.XXX /tmp/test.d8J # mktemp /tmp/test.XXXXXX /tmp/test.cFebDX # mktemp /tmp/test.XXXXXXX /tmp/test.CnyLr7C
創建臨時目錄
# mktemp -d /tmp/tmp.xg5gFj0w8D # mktemp -d --suffix=.tmp /tmp/test.XXXXX /tmp/test.TDpz8.tmp $ mktemp -d --suffix=.tmp -p /tmp deploy.XXXXXX /tmp/deploy.FwebCc.tmp
從安全形度考慮禁止記錄history
ln -s /dev/null .bash_history
定製.bash_history格式
export HISTSIZE=1000 export HISTFILESIZE=2000 export HISTTIMEFORMAT="%Y-%m-%d-%H:%M:%S " export HISTFILE="~/.bash_history"
看看實際效果
$ history | head 1 2012-02-27-09:10:45 do-release-upgrade 2 2012-02-27-09:10:45 vim /etc/network/interfaces 3 2012-02-27-09:10:45 vi /etc/network/interfaces 4 2012-02-27-09:10:45 ping www.163.com
提示 | |
---|---|
CentOS 可以添加到 /etc/bashrc 這樣可以對所有用戶起作用 echo 'export HISTTIMEFORMAT="%Y-%m-%d-%H:%M:%S "' >> /etc/bashrc |
ln -s /dev/null .mysql_history
插入時間點,在~/.bashrc中加入下面命令
$ tail ~/.bashrc echo `date` >> ~/.mysql_history
$ tail ~/.mysql_history EXPLAIN SELECT * FROM stuff where id=3 \G EXPLAIN SELECT * FROM stuff where id='3' \G EXPLAIN SELECT * FROM stuff where id='2' \G Mon Feb 27 09:15:18 CST 2012 EXPLAIN SELECT * FROM stuff where id='2' and created = '2012-02-01' \G EXPLAIN SELECT * FROM stuff where id='1' and created = '2012-02-01' \G EXPLAIN SELECT * FROM stuff where id='3' and created = '2012-02-01' \G EXPLAIN SELECT * FROM stuff where id='2' and created = '2012-02-01' \G EXPLAIN SELECT * FROM stuff where id='2' or created = '2012-02-01' \G EXPLAIN SELECT * FROM stuff where id='2' and created = '2012-02-01' \G Mon Feb 27 11:48:37 CST 2012
hase 命令:用來顯示和清除哈希表,執行命令的時候,系統將先查詢哈希表。
當你輸入命令,首先在hash表中尋找,如果不存在,才會利用$PATH環境變數指定的路徑尋找命令,然後加以執行。同時也會將其放入到hash table 中,當下一次執行同樣的命令時就不會再通過$PATH尋找。以此提高命令的執行效率。
顯示哈希表中命令使用頻率
$ hash hits command 6 /usr/bin/svn 1 /bin/chown 3 /bin/bash 4 /usr/bin/git 12 /usr/bin/php 1 /bin/rm 1 /bin/chmod 1 /usr/bin/nmap 5 /bin/cat 13 /usr/bin/vim 3 /usr/bin/sudo 4 /bin/sed 2 /bin/ps 2 /usr/bin/man 23 /bin/ls
顯示哈希表
$ hash -l builtin hash -p /usr/bin/svn svn builtin hash -p /bin/chown chown builtin hash -p /bin/bash bash builtin hash -p /usr/bin/git git builtin hash -p /usr/bin/php php builtin hash -p /bin/rm rm builtin hash -p /bin/chmod chmod builtin hash -p /usr/bin/nmap nmap builtin hash -p /bin/cat cat builtin hash -p /usr/bin/vim vim builtin hash -p /usr/bin/sudo sudo builtin hash -p /bin/sed sed builtin hash -p /bin/ps ps builtin hash -p /usr/bin/man man builtin hash -p /bin/ls ls
顯示命令的完整路徑
$ hash -t git /usr/bin/git
向哈希表中增加內容
$ hash -p /home/www/deployment/run run $ run Usage: /home/www/deployment/run [OPTION] <server-id> <directory/timepoint> OPTION: development <domain> <host> testing <domain> <host> production <domain> <host> branch {development|testing|production} <domain> <host> <branchname> revert {development|testing|production} <domain> <host> <revision> backup <domain> <host> <directory> release <domain> <host> <tags> <message> list list <domain> <host> clean {development|testing|production} <domain> <host> log <project> <line> conf list cron show cron setup cron edit
命令等同於
PATH=$PATH:$HOME/www/deployment export PATH
刪除哈希表內容
$ hash -r $ hash -l hash: hash table empty
.bashrc
# Prompt definitions if [ -f ~/.bash_prompt ]; then . ~/.bash_prompt fi
.bash_prompt
#!/bin/bash function tonka2 { local GRAY="\[\033[1;30m\]" local LIGHT_GRAY="\[\033[0;37m\]" local WHITE="\[\033[1;37m\]" local LIGHT_BLUE="\[\033[1;34m\]" local LIGHT_RED="\[\033[1;31m\]" local YELLOW="\[\033[1;33m\]" case $TERM in xterm*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="$TITLEBAR\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\u$LIGHT_BLUE@$YELLOW\h\ $LIGHT_BLUE)-(\ $YELLOW\$PWD\ $LIGHT_BLUE)-$YELLOW-\ $LIGHT_GRAY\n\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\$(date +%F)$LIGHT_BLUE:$YELLOW\$(date +%I:%M:%S)\ $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)-$YELLOW-$LIGHT_GRAY " PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$LIGHT_GRAY " } function proml { local BLUE="\[\033[0;34m\]" local RED="\[\033[0;31m\]" local LIGHT_RED="\[\033[1;31m\]" local WHITE="\[\033[1;37m\]" local NO_COLOUR="\[\033[0m\]" case $TERM in xterm*|rxvt*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="${TITLEBAR}\ $BLUE[$RED\$(date +%H%M)$BLUE]\ $BLUE[$LIGHT_RED\u@\h:\w$BLUE]\ $WHITE\$$NO_COLOUR " PS2='> ' PS4='+ ' } function neo_prompt { local GRAY="\[\033[1;30m\]" local LIGHT_GRAY="\[\033[0;37m\]" local WHITE="\[\033[1;37m\]" local LIGHT_BLUE="\[\033[1;34m\]" local LIGHT_RED="\[\033[1;31m\]" local YELLOW="\[\033[1;33m\]" case $TERM in xterm*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="$TITLEBAR\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\$(date +%F)$LIGHT_BLUE $YELLOW\$(date +%I:%M:%S)\ $LIGHT_BLUE)-(\ $YELLOW\$PWD\ $LIGHT_BLUE)-$YELLOW-\ $LIGHT_GRAY\n\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\u$LIGHT_BLUE@$YELLOW\h\ $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)-$YELLOW-$LIGHT_GRAY " PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$LIGHT_GRAY " } # Created by KrON from windowmaker on IRC # Changed by Spidey 08/06 function elite { PS1="\[\033[31m\]\332\304\[\033[34m\](\[\033[31m\]\u\[\033[34m\]@\[\033[31m\]\h\ \[\033[34m\])\[\033[31m\]-\[\033[34m\](\[\033[31m\]\$(date +%I:%M%P)\ \[\033[34m\]-:-\[\033[31m\]\$(date +%m)\[\033[34m\033[31m\]/\$(date +%d)\ \[\033[34m\])\[\033[31m\]\304-\[\033[34m]\\371\[\033[31m\]-\371\371\ \[\033[34m\]\372\n\[\033[31m\]\300\304\[\033[34m\](\[\033[31m\]\W\[\033[34m\])\ \[\033[31m\]\304\371\[\033[34m\]\372\[\033[00m\]" PS2="> " }
例 22.1. A "Power User" Prompt
.bash_prompt
#!/bin/bash #---------------------------------------------------------------------- # POWER USER PROMPT "pprom2" #---------------------------------------------------------------------- # # Created August 98, Last Modified 9 November 98 by Giles # # Problem: when load is going down, it says "1.35down-.08", get rid # of the negative function prompt_command { # Create TotalMeg variable: sum of visible file sizes in current directory local TotalBytes=0 for Bytes in $(ls -l | grep "^-" | awk '{print $5}') do let TotalBytes=$TotalBytes+$Bytes done TotalMeg=$(echo -e "scale=3 \nx=$TotalBytes/1048576\n if (x<1) {print \"0\"} \n print x \nquit" | bc) # This is used to calculate the differential in load values # provided by the "uptime" command. "uptime" gives load # averages at 1, 5, and 15 minute marks. # local one=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\)/\1/" -e "s/ //g") local five=$(uptime | sed -e "s/.*load average: \(.*\...\), \(.*\...\), \(.*\...\).*/\2/" -e "s/ //g") local diff1_5=$(echo -e "scale = scale ($one) \nx=$one - $five\n if (x>0) {print \"up\"} else {print \"down\"}\n print x \nquit \n" | bc) loaddiff="$(echo -n "${one}${diff1_5}")" # Count visible files: let files=$(ls -l | grep "^-" | wc -l | tr -d " ") let hiddenfiles=$(ls -l -d .* | grep "^-" | wc -l | tr -d " ") let executables=$(ls -l | grep ^-..x | wc -l | tr -d " ") let directories=$(ls -l | grep "^d" | wc -l | tr -d " ") let hiddendirectories=$(ls -l -d .* | grep "^d" | wc -l | tr -d " ")-2 let linktemp=$(ls -l | grep "^l" | wc -l | tr -d " ") if [ "$linktemp" -eq "0" ] then links="" else links=" ${linktemp}l" fi unset linktemp let devicetemp=$(ls -l | grep "^[bc]" | wc -l | tr -d " ") if [ "$devicetemp" -eq "0" ] then devices="" else devices=" ${devicetemp}bc" fi unset devicetemp } PROMPT_COMMAND=prompt_command function pprom2 { local BLUE="\[\033[0;34m\]" local LIGHT_GRAY="\[\033[0;37m\]" local LIGHT_GREEN="\[\033[1;32m\]" local LIGHT_BLUE="\[\033[1;34m\]" local LIGHT_CYAN="\[\033[1;36m\]" local YELLOW="\[\033[1;33m\]" local WHITE="\[\033[1;37m\]" local RED="\[\033[0;31m\]" local NO_COLOUR="\[\033[0m\]" case $TERM in xterm*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="$TITLEBAR\ $BLUE[$RED\$(date +%H%M)$BLUE]\ $BLUE[$RED\u@\h$BLUE]\ $BLUE[\ $LIGHT_GRAY\${files}.\${hiddenfiles}-\ $LIGHT_GREEN\${executables}x \ $LIGHT_GRAY(\${TotalMeg}Mb) \ $LIGHT_BLUE\${directories}.\ \${hiddendirectories}d\ $LIGHT_CYAN\${links}\ $YELLOW\${devices}\ $BLUE]\ $BLUE[${WHITE}\${loaddiff}$BLUE]\ $BLUE[\ $WHITE\$(ps ax | wc -l | sed -e \"s: ::g\")proc\ $BLUE]\ \n\ $BLUE[$RED\$PWD$BLUE]\ $WHITE\$\ \ $NO_COLOUR " PS2='> ' PS4='+ ' }
例 22.2. A Prompt the Width of Your Term
#!/bin/bash # termwide prompt with tty number # by Giles - created 2 November 98, last tweaked 31 July 2001 # # This is a variant on "termwide" that incorporates the tty number. # hostnam=$(hostname -s) usernam=$(whoami) temp="$(tty)" # Chop off the first five chars of tty (ie /dev/): cur_tty="${temp:5}" unset temp function prompt_command { # Find the width of the prompt: TERMWIDTH=${COLUMNS} # Add all the accessories below ... local temp="--(${usernam}@${hostnam}:${cur_tty})---(${PWD})--" let fillsize=${TERMWIDTH}-${#temp} if [ "$fillsize" -gt "0" ] then fill="-------------------------------------------------------------------------------------------------------------------------------------------" # It's theoretically possible someone could need more # dashes than above, but very unlikely! HOWTO users, # the above should be ONE LINE, it may not cut and # paste properly fill="${fill:0:${fillsize}}" newPWD="${PWD}" fi if [ "$fillsize" -lt "0" ] then fill="" let cut=3-${fillsize} newPWD="...${PWD:${cut}}" fi } PROMPT_COMMAND=prompt_command function twtty { local WHITE="\[\033[1;37m\]" local NO_COLOUR="\[\033[0m\]" local LIGHT_BLUE="\[\033[1;34m\]" local YELLOW="\[\033[1;33m\]" case $TERM in xterm*|rxvt*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="$TITLEBAR\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\$usernam$LIGHT_BLUE@$YELLOW\$hostnam$LIGHT_BLUE:$WHITE\$cur_tty\ ${LIGHT_BLUE})-${YELLOW}-\${fill}${LIGHT_BLUE}-(\ $YELLOW\${newPWD}\ $LIGHT_BLUE)-$YELLOW-\ \n\ $YELLOW-$LIGHT_BLUE-(\ $YELLOW\$(date +%H%M)$LIGHT_BLUE:$YELLOW\$(date \"+%a,%d %b %y\")\ $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)-\ $YELLOW-\ $NO_COLOUR " PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$NO_COLOUR " }
例 22.3. The Elegant Useless Clock Prompt
#!/bin/bash # This prompt requires a VGA font. The prompt is anchored at the bottom # of the terminal, fills the width of the terminal, and draws a line up # the right side of the terminal to attach itself to a clock in the upper # right corner of the terminal. function prompt_command { # Calculate the width of the prompt: hostnam=$(echo -n $HOSTNAME | sed -e "s/[\.].*//") # "whoami" and "pwd" include a trailing newline usernam=$(whoami) newPWD="${PWD}" # Add all the accessories below ... let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})-----" \ | wc -c | tr -d " ") # Figure out how much to add between user@host and PWD (or how much to # remove from PWD) let fillsize=${COLUMNS}-${promptsize} fill="" # Make the filler if prompt isn't as wide as the terminal: while [ "$fillsize" -gt "0" ] do fill="${fill}Ä" # The A with the umlaut over it (it will appear as a long dash if # you're using a VGA font) is \304, but I cut and pasted it in # because Bash will only do one substitution - which in this case is # putting $fill in the prompt. let fillsize=${fillsize}-1 done # Right-truncate PWD if the prompt is going to be wider than the terminal: if [ "$fillsize" -lt "0" ] then let cutt=3-${fillsize} newPWD="...$(echo -n $PWD | sed -e "s/\(^.\{$cutt\}\)\(.*\)/\2/")" fi # # Create the clock and the bar that runs up the right side of the term # local LIGHT_BLUE="\033[1;34m" local YELLOW="\033[1;33m" # Position the cursor to print the clock: echo -en "\033[2;$((${COLUMNS}-9))H" echo -en "$LIGHT_BLUE($YELLOW$(date +%H%M)$LIGHT_BLUE)\304$YELLOW\304\304\277" local i=${LINES} echo -en "\033[2;${COLUMNS}H" # Print vertical dashes down the side of the terminal: while [ $i -ge 4 ] do echo -en "\033[$(($i-1));${COLUMNS}H\263" let i=$i-1 done let prompt_line=${LINES}-1 # This is needed because doing \${LINES} inside a Bash mathematical # expression (ie. $(())) doesn't seem to work. } PROMPT_COMMAND=prompt_command function clock3 { local LIGHT_BLUE="\[\033[1;34m\]" local YELLOW="\[\033[1;33m\]" local WHITE="\[\033[1;37m\]" local LIGHT_GRAY="\[\033[0;37m\]" local NO_COLOUR="\[\033[0m\]" case $TERM in xterm*) TITLEBAR='\[\033]0;\u@\h:\w\007\]' ;; *) TITLEBAR="" ;; esac PS1="$TITLEBAR\ \[\033[\${prompt_line};0H\] $YELLOW\332$LIGHT_BLUE\304(\ $YELLOW\${usernam}$LIGHT_BLUE@$YELLOW\${hostnam}\ ${LIGHT_BLUE})\304${YELLOW}\304\${fill}${LIGHT_BLUE}\304(\ $YELLOW\${newPWD}\ $LIGHT_BLUE)\304$YELLOW\304\304\304\331\ \n\ $YELLOW\300$LIGHT_BLUE\304(\ $YELLOW\$(date \"+%a,%d %b %y\")\ $LIGHT_BLUE:$WHITE\$$LIGHT_BLUE)\304\ $YELLOW\304\ $LIGHT_GRAY " PS2="$LIGHT_BLUE\304$YELLOW\304$YELLOW\304$NO_COLOUR " }