고급 Bash 스 크 립 트 프로 그래 밍 가이드 (23): 복잡 한 명령

31111 단어 shell
고급 Bash 스 크 립 트 프로 그래 밍 가이드 (23): 복잡 한 명령
성공 과 견지 는 그 치지 않 는 다
더 높 은 사용자 명령
find
find 명령 의 일반 형식:
find pathname -options [-exec]
pathname 은 find 명령 이 찾 는 디 렉 터 리 경로 - exec 가 일치 하 는 파일 을 실행 하 는 셸 명령 - options 옵션 매개 변수 입 니 다. - name 은 파일 이름 에 따라 파일 을 찾 습 니 다. - perm 은 파일 권한 에 따라 파일 을 찾 습 니 다. - user 는 파일 소유자 에 따라 파일 을 찾 습 니 다. - group 은 파일 소속 그룹 에 따라 파일 을 찾 습 니 다. - mtime - n + n 은 파일 변경 시간 에 따라 파일 을 찾 습 니 다.- n 은 n 일 이내, + n 은 n 일 전 - nogroup 에서 그룹 이 없 는 파일 을 찾 습 니 다. - nuser 는 주인 이 없 는 파일 을 찾 습 니 다. - type 은 특정한 유형의 파일 을 찾 습 니 다.     b 블록 장치 파일     디 렉 터 리     c 문자 장치 파일     p 파이프 파일     l 심 볼 릭 링크 파일     f 일반 파일 - iregex 대소 문자 의 정규 표현 식 무시 - regex 정규 표현 식
예 를 들다
root@ubuntu:~/resource/shell-study# find ~/resource/shell-study -name '*.txt'
/root/resource/shell-study/0509-2013/test7/3.txt
/root/resource/shell-study/0507-2013/file.txt
/root/resource/shell-study/0426-2013/txt-folder/file2.txt
/root/resource/shell-study/0426-2013/txt-folder/file1.txt
/root/resource/shell-study/0506-2013/file.txt
root@ubuntu:~/resource/shell-study# 
비교적 특수 한 경우 exec 를 사용 하여 셸 명령 을 실행 하고 형식 요구:
-exec COMMAND\;
- exec 옵션 뒤에 실행 할 명령 을 따 르 고 {} 한 쌍 의 빈 칸 과 한/, 마지막 으로 분점 입 니 다.
모든 find 에 일치 하 는 파일 에서 COMMAND 명령 을 실행 합 니 다. 명령 시퀀스;끝 (";"은 shll 이 find 명령 에 전 달 된 문자 가 다른 특수 문자 로 해석 되 지 않도록 하 는 전의 문자 입 니 다).
COMMAND 에 {} 이 포함 되 어 있 으 면 find 명령 은 "{}"과 일치 하 는 모든 경로 이름 으로 대 체 됩 니 다.
예: 사용자 홈 디 렉 터 리 에서 수정 시간 3 일 전 'txt' 파일 을 찾 아 삭제 합 니 다.
$find . -mtime +3 -name “*.txt” -exec rm {} /; 
다음 find 의 응용 예 를 들 어:
find /home/bozo/projects -mtime 1
#  列出最后一天被修改的
#+ 在/home/bozo/projects目录树下的所有文件.
#
#  mtime = 目标文件最后修改的时间
#  ctime = 修改后的最后状态(通过'chmod'或其他方法)
#  atime = 最后访问时间
DIR=/home/bozo/junk_files
find "$DIR" -type f -atime +5 -exec rm {} \;
#                                      ^^
#  大括号就是"find"命令用来替换目录的地方.
#
#  删除至少5天内没被访问过的
#+ "/home/bozo/junk_files" 中的所有文件.
#
#  "-type filetype", where
#  f = regular file
#  d = directory, etc.
#  ('find' 命令的man页包含有完整的选项列表.)
find /etc -exec grep \
    '[0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*[.][0-9][0-9]*' {} \;

# 在 /etc 目录中的文件找到所所有包含 IP 地址(xxx.xxx.xxx.xxx) 的文件.
# 可能会查找到一些多余的匹配. 我们如何去掉它们呢?

# 或许可以使用如下方法:

find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '
' \ | grep '^[^.][^.]*\.[^.][^.]*\.[^.][^.]*\.[^.][^.]*$' # # [:digit:] 是一种字符类.
세 번 째 인 스 턴 스 는 이해 하기 쉽 지 않 을 수도 있 습 니 다. 괜 찮 습 니 다. 서 두 르 지 마 세 요. 잘 될 겁 니 다. O (∩ ∩) O ~ tr 의 용법 을 먼저 보 여 줍 니 다.
tr (translate 줄 임 말) 는 주로 파일 의 제어 문 자 를 삭제 하거나 문자 변환 을 하 는 데 사 용 됩 니 다.
문법: tr [– c/d/s/t] [SET 1] [SET 2]
SET 1: 문자 집합 1 SET 2: 문자 집합 2 - c: complement, SET 1 에 포함 되 지 않 은 문자 - d: delete 를 SET 1 에 있 는 모든 문 자 를 삭제 하고 변환 하지 않 습 니 다 - s: squeeze - repeats, SET 1 에 중 복 된 문자 - t: truncate - set 1 을 압축 하여 SET 1 을 SET 2 로 변환 합 니 다. 일반적으로 - t 로 부족 합 니 다.
다음은 인 스 턴 스 를 보 겠 습 니 다. 나 쁜 파일 이름 입 니 다. 현재 디 렉 터 리 의 파일 이름 에 나 쁜 문자 가 포함 되 어 있 는 것 을 삭제 합 니 다. (빈 파일 포함)
#!/bin/bash
# badname.sh
# 删除当前目录下文件名中包含一些特殊字符的文件.
# (这些特殊字符指的是不应该出现在文件名中的字符)

for filename in *
do
  badname=`echo "$filename" | sed -n /[\+\{\;\"\\\=\?~\(\)\<\>\&\*\|\$]/p`
# badname=`echo "$filename" | sed -n '/[+{;"\=?~()<>&*|$]/p'`  这句也行.
# 删除文件名包含这些字符的文件:     + { ; " \ = ? ~ ( ) < > & * | $
#
  rm $badname 2>/dev/null
#             ^^^^^^^^^^^ 错误消息将被抛弃.
done

# 现在, 处理文件名中以任何方式包含空白的文件.
find . -name "* *" -exec rm -f {} \;
# "find"命令匹配到的目录名将替换到"{}"的位置.
# '\'是为了保证';'被正确的转义, 并且放到命令的结尾.

exit 0

#---------------------------------------------------------------------
# 这行下边的命令将不会运行, 因为有 "exit" 命令.

# 下边这句可以用来替换上边的脚本:
find . -name '*[+{;"\\=?~()<>&*|$ ]*' -exec rm -f '{}' \;
먼저 위의 인 스 턴 스 를 이해 해 야 합 니 다. sed 라 는 명령 을 알 아야 합 니 다.
sed 편집기 에서 입력 을 한 줄 씩 처리 한 다음 결 과 를 화면 으로 보 냅 니 다.
- i 옵션: 원본 파일 을 직접 사용 합 니 다. 원본 파일 이 수 정 됩 니 다. sed 명령 과 옵션: a\\현재 줄 뒤에 한 줄 또는 여러 줄 을 추가 합 니 다.모드 버퍼 G 로 복사 하여 임시 저장 버퍼 의 내용 을 가 져 옵 니 다. 모드 버퍼 l 에 추가 하여 인쇄 되 지 않 은 문자 p 인쇄 줄 n 을 다음 줄 로 읽 고, 첫 번 째 명령 이 아 닌 다음 줄 에서 처리 q 가 끝나 거나 sed r 를 종료 하여 파일 에서 입력 줄 을 읽 습 니 다. 선택 한 줄 이외 의 줄 에 모든 명령 s 를 하나의 문자열 로 다른 문자열 을 대체 합 니 다.
바 꾸 기 플래그: g 줄 에서 전역 바 꾸 기 p 인쇄 줄 w 는 줄 을 파일 x 에 기록 하고 임시 저장 버퍼 와 패턴 공간의 내용 y 를 바 꾸 어 문 자 를 다른 문자 로 변환 합 니 다.
sed 예: 인쇄: p 명령 sed '/abc/p' 파일        인쇄 file 에는 abc 줄 이 포함 되 어 있 습 니 다. 기본 값 sed 는 모든 줄 을 화면 에 인쇄 합 니 다. 한 줄 이 패턴 에 맞 으 면 이 줄 을 sed - n '/abc/p' file 을 다시 인쇄 합 니 다.   위 와 마찬가지 로 기본 상황 sed 를 제거 하고 모든 줄 을 화면 에 인쇄 합 니 다.
다음 인 스 턴 스 를 보 겠 습 니 다: 파일 의 inode 번 호 를 통 해 파일 을 삭제 합 니 다.
#!/bin/bash

#  当文件名以一个非法字符开头的时候, 这就非常有用了,
#+ 比如 ? 或 -.

ARGCOUNT=1                      # 文件名参数必须被传递到脚本中.
E_WRONGARGS=70
E_FILE_NOT_EXIST=71
E_CHANGED_MIND=72

if [ $# -ne "$ARGCOUNT" ]
then
  echo "Usage: `basename $0` filename"
  exit $E_WRONGARGS
fi

if [ ! -e "$1" ]
then
  echo "File \""$1"\" does not exist."
  exit $E_FILE_NOT_EXIST
fi

inum=`ls -i | grep "$1" | awk '{print $1}'`
# inum = inode 文件的(索引节点)号.
# --------------------------------------------------------
# 每个文件都有一个inode号, 这个号用来记录文件物理地址信息.
# --------------------------------------------------------

echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? "
# 'rm' 命令的 '-v' 选项得询问也会出现这句话.
read answer
case "$answer" in
[nN]) echo "Changed your mind, huh?"
      exit $E_CHANGED_MIND
      ;;
*)    echo "Deleting file \"$1\".";;
esac

find . -inum $inum -exec rm {} \;
#                           ^^
#        大括号就是"find"命令
#+       用来替换文本输出的地方.
echo "File "\"$1"\" deleted!"

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# touch file1
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# chmod +x test1.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ./test1.sh file1 

Are you absolutely sure you want to delete "file1" (y/n)? y
Deleting file "file1".
File "file1" deleted!
root@ubuntu:~/resource/shell-study/0618-2013# 
위의 실례 는 아마도 아래 의 이 문장의 뜻 을 이해 하지 못 할 것 이다
inum=`ls -i | grep "$1"| awk '{print $1}'`
그렇게 지도 모른다, 아마, 아마...
root@ubuntu:~/resource/shell-study/0618-2013# touch file1
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# ls -i
695725 file1  695724 test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# ls -i | grep file1
695725 file1
root@ubuntu:~/resource/shell-study/0618-2013# ls -i | grep file1 | awk '{print $1}'
695725
root@ubuntu:~/resource/shell-study/0618-2013# 
많이 보면 자 연 스 럽 게 됩 니 다. 조급해 하지 마 세 요. O (∩ ∩) O ~
xargs
이것 은 명령 에 매개 변 수 를 전달 하 는 필터 이자 여러 명령 을 조합 하 는 도구 입 니 다. 하나의 데이터 흐름 을 충분 한 작은 블록 으로 나 누 어 필터 와 명령 을 처리 할 수 있 도록 합 니 다. 따라서 이 명령 은 나중에 참조 하 는 강력 한 교체 이기 도 합 니 다. 같은 상황 에서 너무 많은 매개 변 수 를 사용 하 는 명령 을 교체 하 는 데 실패 할 수 있 습 니 다. 이 럴 때 xarg 를 사용 합 니 다.s 명령 으로 바 꿀 수 있 습 니 다. 일반적으로 xargs 는 stdin 이나 파이프 에서 데 이 터 를 읽 지만 파일 의 출력 에서 도 데 이 터 를 읽 을 수 있 습 니 다.
xargs 의 기본 명령 은 echo 입 니 다. 이것 은 파 이 프 를 통 해 xargs 에 전달 하 는 입력 은 줄 바 꿈 과 공백 을 포함 하지만 xargs 의 처 리 를 통 해 줄 바 꿈 과 공백 은 빈 칸 으로 대 체 됩 니 다.
root@ubuntu:~/resource/shell-study/0618-2013# ls -l
total 4
-rw-r--r-- 1 root root    0 2013-06-18 03:35 file1
-rwxr-xr-x 1 root root 1178 2013-06-18 03:31 test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# ls -l | xargs
total 4 -rw-r--r-- 1 root root 0 2013-06-18 03:35 file1 -rwxr-xr-x 1 root root 1178 2013-06-18 03:31 test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# find . -type f | xargs grep "echo"
./test1.sh:  echo "Usage: `basename $0` filename"
./test1.sh:  echo "File \""$1"\" does not exist."
./test1.sh:echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? "
./test1.sh:[nN]) echo "Changed your mind, huh?"
./test1.sh:*)    echo "Deleting file \"$1\".";;
./test1.sh:echo "File "\"$1"\" deleted!"
root@ubuntu:~/resource/shell-study/0618-2013# 
제3 조 명령 을 분해 하 는데 과정 은 다음 과 같다.
root@ubuntu:~/resource/shell-study/0618-2013# find . -type f
./test1.sh
./file1
root@ubuntu:~/resource/shell-study/0618-2013# grep "echo" ./test1.sh 
  echo "Usage: `basename $0` filename"
  echo "File \""$1"\" does not exist."
echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? "
[nN]) echo "Changed your mind, huh?"
*)    echo "Deleting file \"$1\".";;
echo "File "\"$1"\" deleted!"
root@ubuntu:~/resource/shell-study/0618-2013# grep "echo" ./file1 
root@ubuntu:~/resource/shell-study/0618-2013# 
s | xargs - p - l gzip 는 gzip 을 사용 하여 현재 디 렉 터 리 에 있 는 모든 파일 을 압축 하고 매번 압축 하기 전에 사용자 에 게 알려 줍 니 다.
재 미 있 는 xargs 옵션 은 - n NN 입 니 다. NN 은 매개 변 수 를 전달 할 때마다 개 수 를 제한 합 니 다. ls | xargs - n 8 echo 는 현재 디 렉 터 리 에 있 는 모든 파일 을 줄 당 8 열 로 표시 합 니 다.
root@ubuntu:~/resource/shell-study/0618-2013# ls -l | xargs echo
total 4 -rw-r--r-- 1 root root 0 2013-06-18 03:35 file1 -rwxr-xr-x 1 root root 1178 2013-06-18 03:31 test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# ls -l | xargs -n 8 echo
total 4 -rw-r--r-- 1 root root 0 2013-06-18
03:35 file1 -rwxr-xr-x 1 root root 1178 2013-06-18
03:31 test1.sh
root@ubuntu:~/resource/shell-study/0618-2013# ls | xargs -p -l gzip
gzip file1 ?...n
gzip test1.sh ?...n
gzip ?...n
root@ubuntu:~/resource/shell-study/0618-2013# 

xargs 를 사용 하여 시스템 log 를 감시 합 니 다.
#!/bin/bash

# 从/var/log/messagesGenerates的尾部开始
# 产生当前目录下的一个lof文件.

# 注意: 如果这个脚本被一个一般用户调用的话,
# /var/log/messages 必须是全部可读的.
#         #root chmod 644 /var/log/messages

LINES=5

( date; uname -a ) >>logfile
# 时间和机器名
echo ----------------------------------------------------- >>logfile
tail -$LINES /var/log/messages | xargs |  fmt -s >>logfile
echo >>logfile
echo >>logfile

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# chmod +x test2.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  test1.sh  test2.sh
root@ubuntu:~/resource/shell-study/0618-2013# ./test2.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  logfile  test1.sh  test2.sh
root@ubuntu:~/resource/shell-study/0618-2013# cat logfile 
Tue Jun 18 04:01:14 PDT 2013
Linux ubuntu 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:10:02 UTC 2010 i686 GNU/Linux
-----------------------------------------------------
Jun 13 02:45:31 ubuntu kernel: [72501.550212] usb 2-2.1: configuration
#1 chosen from 1 choice Jun 13 17:49:43 ubuntu kernel: [81810.618878]
usb 2-2.1: USB disconnect, address 13 Jun 13 17:49:43 ubuntu kernel:
[81811.143471] usb 2-2.1: new full speed USB device using uhci_hcd and
address 14 Jun 13 17:49:43 ubuntu kernel: [81811.267228] usb 2-2.1:
configuration #1 chosen from 1 choice Jun 14 03:04:53 ubuntu kernel:
[99875.994737] usb 2-2.1: USB disconnect, address 14


root@ubuntu:~/resource/shell-study/0618-2013# 
부분 명령 분해:
root@ubuntu:~/resource/shell-study# tail -5 /var/log/messages | xargs
Jun 13 17:49:43 ubuntu kernel: [81810.618878] usb 2-2.1: USB disconnect, address 13 Jun 13 17:49:43 ubuntu kernel: [81811.143471] usb 2-2.1: new full speed USB device using uhci_hcd and address 14 Jun 13 17:49:43 ubuntu kernel: [81811.267228] usb 2-2.1: configuration #1 chosen from 1 choice Jun 14 03:04:53 ubuntu kernel: [99875.994737] usb 2-2.1: USB disconnect, address 14 Jun 18 04:03:34 ubuntu kernel: [118985.358071] hrtimer: interrupt took 15168861 ns
root@ubuntu:~/resource/shell-study# tail -5 /var/log/messages | xargs | fmt -s
Jun 13 17:49:43 ubuntu kernel: [81810.618878] usb 2-2.1: USB disconnect,
address 13 Jun 13 17:49:43 ubuntu kernel: [81811.143471] usb 2-2.1:
new full speed USB device using uhci_hcd and address 14 Jun 13 17:49:43
ubuntu kernel: [81811.267228] usb 2-2.1: configuration #1 chosen from
1 choice Jun 14 03:04:53 ubuntu kernel: [99875.994737] usb 2-2.1: USB
disconnect, address 14 Jun 18 04:03:34 ubuntu kernel: [118985.358071]
hrtimer: interrupt took 15168861 ns
root@ubuntu:~/resource/shell-study# 
다른 인 스 턴 스: 현재 디 렉 터 리 에 있 는 파일 을 다른 파일 로 복사 합 니 다.
#!/bin/bash

#  将当前目录下($PWD)的所有文件都拷贝到
#+ 命令行所指定的另一个目录中去.

E_NOARGS=65

if [ -z "$1" ]   # 如果没有参数传递进来那就退出.
then
  echo "Usage: `basename $0` directory-to-copy-to"
  exit $E_NOARGS
fi

ls . | xargs -i -t cp ./{} $1
#            ^^ ^^      ^^
#  -t 是 "verbose" (输出命令行到stderr) 选项.
#  -i 是"替换字符串"选项.
#  {} 是输出文本的替换点.
#  这与在"find"命令中使用{}的情况很相像.
#
#  列出当前目录下的所有文件(ls .),
#+ 将 "ls" 的输出作为参数传递到 "xargs"(-i -t 选项) 中,
#+ 然后拷贝(cp)这些参数({})到一个新目录中($1).
#
#  最终的结果和下边的命令等价,
#+   cp * $1
#+ 除非有文件名中嵌入了"空白"字符.

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  logfile  test1.sh  test2.sh  test3.sh
root@ubuntu:~/resource/shell-study/0618-2013# cd ..
root@ubuntu:~/resource/shell-study# ls
0426-2013  0427-2013  0504-2013  0506-2013  0507-2013  0508-2013  0509-2013  0609-2013  0613-2013  0614-2013  0615-2013  0618-2013
root@ubuntu:~/resource/shell-study# mkdir tests
root@ubuntu:~/resource/shell-study# ls
0426-2013  0427-2013  0504-2013  0506-2013  0507-2013  0508-2013  0509-2013  0609-2013  0613-2013  0614-2013  0615-2013  0618-2013  tests
root@ubuntu:~/resource/shell-study# cd 0618-2013/
root@ubuntu:~/resource/shell-study/0618-2013# chmod +x test3.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ./test3.sh ./../tests/
cp ./file1 ./../tests/ 
cp ./logfile ./../tests/ 
cp ./test1.sh ./../tests/ 
cp ./test2.sh ./../tests/ 
cp ./test3.sh ./../tests/ 
root@ubuntu:~/resource/shell-study/0618-2013# cd ../tests/
root@ubuntu:~/resource/shell-study/tests# ls
file1  logfile  test1.sh  test2.sh  test3.sh
root@ubuntu:~/resource/shell-study/tests# 
계속 인 스 턴 스: 이름 kill 프로 세 스 를 통 해
#!/bin/bash

#  例如,
#+ 试一下 "./file.sh xterm" --
#+ 并且查看你系统上的所有xterm都将消失.

#  警告:
#  -----
#  这是一个非常危险的脚本.
#  运行它的时候一定要小心. (尤其是以root身份运行时)
#+ 因为运行这个脚本可能会引起数据丢失或产生其他一些不好的效果.

E_BADARGS=66

if test -z "$1"  # 没有参数传递进来?
then
  echo "Usage: `basename $0` Process(es)_to_kill"
  exit $E_BADARGS
fi


PROCESS_NAME="$1"
ps ax | grep "$PROCESS_NAME" | awk '{print $1}' | xargs -i kill {} 2&>/dev/null
#                                                       ^^      ^^

# -----------------------------------------------------------
# 注意:
# -i 参数是xargs命令的"替换字符串"选项.
# 大括号对的地方就是替换点.
# 2&>/dev/null 将会丢弃不需要的错误消息.
# -----------------------------------------------------------

exit $?

#  在这个脚本中, "killall"命令具有相同的效果,
#+ 但是这么做就没有教育意义了.
부분 명령 분해:
root@ubuntu:~/resource/shell-study/0618-2013# ps ax
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:01 /sbin/init
    2 ?        S      0:00 [kthreadd]
    3 ?        S      0:00 [migration/0]
    4 ?        S      0:00 [ksoftirqd/0]
    5 ?        S      0:00 [watchdog/0]
    6 ?        S      0:00 [events/0]
    7 ?        S      0:00 [cpuset]
    8 ?        S      0:00 [khelper]
    9 ?        S      0:00 [netns]
   10 ?        S      0:00 [async/mgr]
   11 ?        S      0:00 [pm]
   12 ?        S      0:00 [sync_supers]
   13 ?        S      0:00 [bdi-default]
   14 ?        S      0:00 [kintegrityd/0]
   15 ?        S      0:00 [kblockd/0]
   16 ?        S      0:00 [kacpid]
   17 ?        S      0:00 [kacpi_notify]
   18 ?        S      0:00 [kacpi_hotplug]
   19 ?        S      5:22 [ata/0]
   20 ?        S      0:00 [ata_aux]
   21 ?        S      0:00 [ksuspend_usbd]
   22 ?        S      0:00 [khubd]
   23 ?        S      0:00 [kseriod]
   24 ?        S      0:00 [kmmcd]
   27 ?        S      0:00 [khungtaskd]
   28 ?        S      0:00 [kswapd0]
   29 ?        SN     0:00 [ksmd]
   30 ?        S      0:00 [aio/0]
   31 ?        S      0:00 [ecryptfs-kthrea]
   32 ?        S      0:00 [crypto/0]
   35 ?        S      0:00 [pciehpd]
   37 ?        S      0:00 [scsi_eh_0]
   38 ?        S      0:14 [scsi_eh_1]
   41 ?        S      0:00 [kstriped]
   42 ?        S      0:00 [kmpathd/0]
   43 ?        S      0:00 [kmpath_handlerd]
   44 ?        S      0:00 [ksnapd]
   45 ?        S      0:00 [kondemand/0]
   46 ?        S      0:00 [kconservative/0]
  132 ?        S      0:00 [usbhid_resumer]
  238 ?        S      0:00 [mpt_poll_0]
  240 ?        S      0:00 [mpt/0]
  248 ?        S      0:00 [scsi_eh_2]
  265 ?        S      0:06 [jbd2/sda1-8]
  266 ?        S      0:00 [ext4-dio-unwrit]
  326 ?        S      0:00 upstart-udev-bridge --daemon
  328 ?        S<s    0:00 udevd --daemon
  571 ?        S      0:00 [kpsmoused]
  667 ?        S      0:00 [kgameportd]
  721 ?        Ss     0:00 portmap
  746 ?        Sl     0:00 rsyslogd -c4
  760 ?        Ss     0:03 dbus-daemon --system --fork
  776 ?        Ss     0:00 rpc.statd -L
  778 ?        Ssl    0:00 NetworkManager
  782 ?        S      0:00 avahi-daemon: running [ubuntu-2.local]
  784 ?        S      0:00 /usr/sbin/modem-manager
  785 ?        Ss     0:00 avahi-daemon: chroot helper
  797 ?        S      0:00 /sbin/wpa_supplicant -u -s
  843 tty4     Ss+    0:00 /sbin/getty -8 38400 tty4
  849 tty5     Ss+    0:00 /sbin/getty -8 38400 tty5
  857 tty2     Ss+    0:00 /sbin/getty -8 38400 tty2
  858 tty3     Ss+    0:00 /sbin/getty -8 38400 tty3
  860 tty6     Ss+    0:00 /sbin/getty -8 38400 tty6
  861 ?        Ss     0:00 acpid -c /etc/acpi/events -s /var/run/acpid.socket
  867 ?        Ss     0:00 cron
  868 ?        Ss     0:00 atd
  876 ?        S<     0:00 udevd --daemon
  878 ?        S      0:00 [rpciod/0]
  938 ?        S      0:00 [lockd]
  939 ?        S      0:00 [nfsd4]
  940 ?        S      0:00 [nfsd]
  941 ?        S      0:00 [nfsd]
  942 ?        S      0:00 [nfsd]
  943 ?        S      0:00 [nfsd]
  944 ?        S      0:00 [nfsd]
  945 ?        S      0:00 [nfsd]
  946 ?        S      0:00 [nfsd]
  947 ?        S      0:00 [nfsd]
  951 ?        Ss     0:00 /usr/sbin/rpc.mountd --manage-gids
 1008 ?        Ss     0:00 /usr/sbin/cupsd -C /etc/cups/cupsd.conf
 1152 tty1     Ss+    0:00 /sbin/getty -8 38400 tty1
 1182 ?        S      0:00 [vmmemctl]
 1407 ?        Ssl    0:00 /usr/sbin/vmware-vmblock-fuse -o subtype=vmware-vmblock,default_permissions,allow_other /var/run/vmblock-fuse
 1427 ?        S      0:39 /usr/sbin/vmtoolsd
 1475 ?        Ss     0:00 tpvmlpd2
 1483 ?        Ssl    0:00 gdm-binary
 1487 ?        Sl     0:00 /usr/sbin/console-kit-daemon --no-daemon
 1552 ?        Sl     0:00 /usr/lib/gdm/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1
 1557 tty7     Rs+   11:40 /usr/bin/X :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-VvNKCd/database -nolisten tcp vt7
 1602 ?        S      0:00 /usr/bin/dbus-launch --exit-with-session
 1621 ?        Sl     0:00 /usr/lib/gdm/gdm-session-worker
 1625 ?        S      0:00 /usr/lib/upower/upowerd
 1629 ?        SNl    0:00 /usr/lib/rtkit/rtkit-daemon
 1633 ?        S      0:00 /usr/lib/policykit-1/polkitd
 1667 ?        Ssl    0:00 /usr/sbin/hald
 1668 ?        S      0:00 hald-runner
 1697 ?        S      0:00 hald-addon-input: Listening on /dev/input/event2 /dev/input/event0
 1706 ?        S      0:10 hald-addon-storage: polling /dev/sr0 (every 2 sec)
 1711 ?        S      0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
 1712 ?        S      0:00 hald-addon-storage: no polling on /dev/fd0 because it is explicitly disabled
 1726 ?        Sl     0:00 /usr/bin/gnome-keyring-daemon --daemonize --login
 1744 ?        Ssl    0:00 gnome-session
 1779 ?        Ss     0:00 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session gnome-session
 1782 ?        S      0:00 /usr/bin/dbus-launch --exit-with-session gnome-session
 1783 ?        Ss     0:01 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session
 1786 ?        S      0:03 /usr/lib/libgconf2-4/gconfd-2
 1792 ?        Ss     0:12 /usr/lib/gnome-settings-daemon/gnome-settings-daemon
 1795 ?        S      0:00 /usr/lib/gvfs/gvfsd
 1799 ?        Ssl    0:00 /usr/lib/gvfs//gvfs-fuse-daemon /root/.gvfs
 1806 ?        S      1:39 /usr/lib/vmware-tools/sbin32/vmtoolsd -n vmusr --blockFd 3
 1808 ?        S      0:00 /usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1
 1811 ?        S      0:00 gnome-power-manager
 1813 ?        S      0:45 gnome-panel
 1816 ?        S      0:02 nm-applet --sm-disable
 1819 ?        S      0:33 nautilus
 1820 ?        S      0:27 metacity --replace
 1822 ?        S      0:00 bluetooth-applet
 1830 ?        S      0:00 /usr/lib/gvfs/gvfs-gdu-volume-monitor
 1835 ?        S      0:00 /usr/lib/udisks/udisks-daemon
 1836 ?        S      0:04 udisks-daemon: polling /dev/sr0
 1844 ?        Sl     0:00 /usr/lib/gvfs/gvfs-afc-volume-monitor
 1852 ?        S      0:00 /usr/lib/gvfs/gvfs-gphoto2-volume-monitor
 1854 ?        S      0:01 /usr/lib/gvfs/gvfsd-trash --spawner :1.6 /org/gtk/gvfs/exec_spaw/0
 1885 ?        Ss     0:00 gnome-screensaver
 1887 ?        S      0:00 /usr/lib/gvfs/gvfsd-burn --spawner :1.6 /org/gtk/gvfs/exec_spaw/1
 1893 ?        S      0:00 /usr/lib/gvfs/gvfsd-metadata
 1896 ?        S      0:00 /usr/lib/gnome-disk-utility/gdu-notification-daemon
 1900 ?        Ssl    0:00 /usr/lib/bonobo-activation/bonobo-activation-server --ac-activate --ior-output-fd=19
 1906 ?        S      0:00 python /usr/share/system-config-printer/applet.py
 1908 ?        Sl     0:00 /usr/lib/evolution/2.28/evolution-alarm-notify
 1920 ?        S      0:05 /usr/lib/gnome-panel/clock-applet --oaf-activate-iid=OAFIID:GNOME_ClockApplet_Factory --oaf-ior-fd=20
 1970 ?        S      0:52 /usr/lib/gnome-panel/wnck-applet --oaf-activate-iid=OAFIID:GNOME_Wncklet_Factory --oaf-ior-fd=21
 1977 ?        S      0:04 /usr/lib/gnome-applets/trashapplet --oaf-activate-iid=OAFIID:GNOME_Panel_TrashApplet_Factory --oaf-ior-fd=22
 2030 ?        S      0:00 /usr/lib/gnome-panel/notification-area-applet --oaf-activate-iid=OAFIID:GNOME_NotificationAreaApplet_Factory --oaf-ior-fd=24
 2039 ?        S      0:07 /usr/lib/notify-osd/notify-osd
 2090 ?        Sl     1:37 gnome-terminal
 2091 ?        S      0:00 gnome-pty-helper
 2160 ?        S      0:00 /usr/lib/gvfs/gvfsd-computer --spawner :1.6 /org/gtk/gvfs/exec_spaw/2
 2194 ?        S<     0:00 udevd --daemon
 2195 ?        S      0:00 [bluetooth]
 2213 ?        S<     0:00 [krfcommd]
18642 pts/1    Ss+    0:00 bash
20791 pts/0    Ss+    0:00 bash
30574 ?        S      0:00 /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /var/run/dhclient-eth2.pid -lf /var/lib/dhcp3/dhclient-fed0d93f-d7c1-
30846 ?        S      0:00 [flush-8:0]
31249 pts/2    Ss     0:00 bash
31260 pts/2    R+     0:00 ps ax
root@ubuntu:~/resource/shell-study/0618-2013# ps ax | grep "xterm" | awk '{print $1}'
31262
root@ubuntu:~/resource/shell-study/0618-2013# 
계속 인 스 턴 스: xargs 를 사용 하여 단어 가 나타 나 는 빈 도 를 분석 합 니 다.
#!/bin/bash
# 分析一个文本文件中单词出现的频率.

# 使用 'xargs' 将文本行分解为单词.

# 检查命令行上输入的文件.
ARGS=1
E_BADARGS=65
E_NOFILE=66

if [ $# -ne "$ARGS" ]
# 纠正传递到脚本中的参数个数?
then
  echo "Usage: `basename $0` filename"
  exit $E_BADARGS
fi

if [ ! -f "$1" ]       # 检查文件是否存在.
then
  echo "File \"$1\" does not exist."
  exit $E_NOFILE
fi



#####################################################################
cat "$1" | xargs -n1 | \
#  列出文件, 每行一个单词.
tr A-Z a-z | \
#  将字符转换为小写.
sed -e 's/\.//g'  -e 's/\,//g' -e 's/ /\
/g' | \
#  过滤掉句号和逗号,
#+ 并且将单词间的空格修改为换行,
sort | uniq -c | sort -nr
#  最后统计出现次数, 把数字显示在第一列, 然后显示单词, 并按数字排序.
#####################################################################

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# chmod +x test5.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ls
file1  logfile  test1.sh  test2.sh  test3.sh  test4.sh  test5.sh
root@ubuntu:~/resource/shell-study/0618-2013# ./test5.sh test1.sh 
xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
      2 then
      2 if
      2 echo
      2 #
      2 ]
      2 [
      1 这就非常有用了
      1 比如
      1 文件名参数必须被传递到脚本中
      1 或
      1 当文件名以一个非法字符开头的时候
      1 usage:
      1 not
      1 filename
      1 file
      1 fi
      1 exit
      1 e_wrongargs=70
      1 $e_wrongargs
      1 e_file_not_exist=71
      1 e_changed_mind=72
      1 does
      1 #!/bin/bash
      1 `basename
      1 argcount=1
      1 $argcount
      1 \$1"
      1 $1
      1 $0`
      1 #+
      1 $#
      1 ?
      1 !
      1 -
      1 
root@ubuntu:~/resource/shell-study/0618-2013#

expr
유 니 버 설 값 표현 식: 주어진 작업 (파 라 메 터 는 빈 칸 으로 구분 해 야 합 니 다) 을 통 해 파 라 메 터 를 연결 하고 파 라 메 터 를 구 합 니 다. 산술 작업, 비교 작업, 문자열 작업 또는 논리 작업 을 할 수 있 습 니 다. expr 3 + 5 를 8 로 되 돌려 줍 니 다.
expr 5% 3 반환 2
expr 1/0 오류 메 시 지 를 되 돌려 줍 니 다. expr: division by zero
불법 산술 조작 은 허용 되 지 않 습 니 다.
expr 5\\* 3 반환 15
산술 식 expr 에서 곱셈 조작 을 사용 할 때 곱셈 기 호 는 반드시 전의 되 어야 합 니 다.
y = 'expr $y + 1' 변수의 값 을 증가 시 킵 니 다. let y = y + 1 과 y = $($y + 1) 의 효과 와 같 습 니 다. 이것 은 산술 표현 식 을 사용 하 는 예 입 니 다.
z = ` expr substr $string $position $length ` 위치 $position 에서 $length 길이 의 하위 문자열 을 추출 합 니 다. expr 를 사용 하 는 인 스 턴 스:
#!/bin/bash

# 展示一些使用'expr'的例子
# ========================

echo

# 算术 操作
# ---- ----

echo "Arithmetic Operators"
echo
a=`expr 5 + 3`
echo "5 + 3 = $a"

a=`expr $a + 1`
echo
echo "a + 1 = $a"
echo "(incrementing a variable)"

a=`expr 5 % 3`
# 取模操作
echo
echo "5 mod 3 = $a"

echo
echo

# 逻辑 操作
# ---- ----

#  true返回1, false返回0,
#+ 而Bash的使用惯例则相反.

echo "Logical Operators"
echo

x=24
y=25
b=`expr $x = $y`         # 测试相等.
echo "b = $b"            # 0  ( $x -ne $y )
echo

a=3
b=`expr $a \> 10`
echo "If a > 10, b = 0 (false)"
echo "b = $b"            # 0  ( 3 ! -gt 10 )
echo

b=`expr $a \< 10`
echo "If a < 10, b = 1 (true)"
echo "b = $b"            # 1  ( 3 -lt 10 )
echo
# 注意转义操作.

b=`expr $a \<= 3`
echo "If a <= 3, b = 1 (true)"
echo "b = $b"            # 1  ( 3 -le 3 )
# 也有 "\>=" 操作 (大于等于).


echo
echo



# 字符串 操作
# ------ ----

echo "String Operators"
echo

a=1234zipper43231
echo "The string being operated upon is \"$a\"."

# 长度: 字符串长度
b=`expr length $a`
echo "Length of \"$a\" is $b."

# 索引: 从字符串的开头查找匹配的子串,
#       并取得第一个匹配子串的位置.
b=`expr index $a 23`
echo "Numerical position of first \"2\" in \"$a\" is \"$b\"."

# substr: 从指定位置提取指定长度的字串.
b=`expr substr $a 2 6`
echo "Substring of \"$a\", starting at position 2,\
and 6 chars long is \"$b\"."


#  'match' 操作的默认行为就是从字符串的开始进行搜索,
#+  并匹配第一个匹配的字符串.
#
#        使用正则表达式
b=`expr match "$a" '[0-9]*'`               #  数字的个数.
echo Number of digits at the beginning of \"$a\" is $b.
b=`expr match "$a" '\([0-9]*\)'`           #  注意, 需要转义括号
#                   ==      ==              + 这样才能触发子串的匹配.
echo "The digits at the beginning of \"$a\" are \"$b\"."

echo

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# ./test6.sh 

Arithmetic Operators

5 + 3 = 8

a + 1 = 9
(incrementing a variable)

5 mod 3 = 2


Logical Operators

b = 0

If a > 10, b = 0 (false)
b = 0

If a < 10, b = 1 (true)
b = 1

If a <= 3, b = 1 (true)
b = 1


String Operators

The string being operated upon is "1234zipper43231".
Length of "1234zipper43231" is 15.
Numerical position of first "2" in "1234zipper43231" is "2".
Substring of "1234zipper43231", starting at position 2,and 6 chars long is "234zip".
Number of digits at the beginning of "1234zipper43231" is 4.
The digits at the beginning of "1234zipper43231" are "1234".

root@ubuntu:~/resource/shell-study/0618-2013# 
계속 인 스 턴 스:
#!/bin/bash

echo
echo "String operations using \"expr \$string : \" construct"
echo "==================================================="
echo

a=1234zipper5FLIPPER43231

echo "The string being operated upon is \"`expr "$a" : '\(.*\)'`\"."
#     转义括号对的操作.	==  ==

#       ***************************
#+              转义括号对
#+          用来匹配一个子串
#       ***************************


#  如果不转义括号的话...
#+ 那么'expr'将把string操作转换为一个整数.

echo "Length of \"$a\" is `expr "$a" : '.*'`."   # 字符串长度

echo "Number of digits at the beginning of \"$a\" is `expr "$a" : '[0-9]*'`."

# ------------------------------------------------------------------------- #

echo

echo "The digits at the beginning of \"$a\" are `expr "$a" : '\([0-9]*\)'`."
#                                                             ==      ==
echo "The first 7 characters of \"$a\" are `expr "$a" : '\(.......\)'`."
#         =====                                          ==       ==
# 再来一个, 转义括号对强制一个子串匹配.
#
echo "The last 7 characters of \"$a\" are `expr "$a" : '.*\(.......\)'`."
#         ====                  字符串操作的结尾		^^
#  (最后这个模式的意思是忽略前边的任何字符,直到最后7个字符,
#+  最后7个点就是需要匹配的任意7个字符的字串)

echo

exit 0
결과:
root@ubuntu:~/resource/shell-study/0618-2013# chmod +x test7.sh 
root@ubuntu:~/resource/shell-study/0618-2013# ./test7.sh 

String operations using "expr $string : " construct
===================================================

The string being operated upon is "1234zipper5FLIPPER43231".
Length of "1234zipper5FLIPPER43231" is 23.
Number of digits at the beginning of "1234zipper5FLIPPER43231" is 4.

The digits at the beginning of "1234zipper5FLIPPER43231" are 1234.
The first 7 characters of "1234zipper5FLIPPER43231" are 1234zip.
The last 7 characters of "1234zipper5FLIPPER43231" are ER43231.

root@ubuntu:~/resource/shell-study/0618-2013# 

먼저 여기까지, O (∩ ∩) O ~
내 칼럼 주소:http://blog.csdn.net/column/details/shell-daily-study.html
계속...

좋은 웹페이지 즐겨찾기