shell

shell 脚本的第一行一般为:

#! /bin/sh

ll /bin/sh 可以发现 sh 是一个指向 bash 的软连接。脚本文件一般有两种运行方式,一种是作为 sh 命令的命令行参数,另一种是将脚本作为具有可执行权限的可执行文件,对于后一种方式来说,上面的那句话就有作用了,它指定了调用哪种解释器来运行脚本。

 

date:用于显示和设置时间

#输出时间:
date        #以本地时间格式输出当前时间
date +%s    #以时间戳形式输出当前时间

#本地时间格式与时间戳转换:
date +%s -d "2013/9/23 10:40:00"    #将指定时间转换成时间戳>格式
date -d @1379895103     #指定时间戳转换成本地时间格式

#设置时间:
date -s 2013/9/23     # date -s 2013-9-23
date -s 10:30:00
date -s "2013/9/23 10:30:00"

 

time:计算某一任务运行的时间。通过 type -a time 查看,可以发现 linux 中有两个 time,还有一个是 /usr/bin/time ,没有可安装,它显示的信息比下面会更多一些,包括一些CPU占用和IO等情况,使用方法如 /usr/bin/time -v make -j4,此处略过。

# TIMEFORMAT 环境变量用来自定义输出的时间格式
export TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S'    # 有 -p 参数的时间格式
time date
export TIMEFORMAT=$'real %2R\n' # 只输出 real 时间
time date
export TIMEFORMAT=$'\nreal\t%3lR\nuser\t%3lU\nsys\t%3lS'    #默认时间格式
time date
time -p date    # -p 参数可以指定以 POSIX 缺省时间格式打印结果,单位为秒

 

who: show who is logged on

who -aH     #输出系统上次引导时间、当前运行级别和当前登陆用户,及其它用户登陆信息,-H 表示显示表头(即标题)
who -b      # -b: boot 上次引导时间
who -r      # -r: run 当前运行级别,同 runlevel
who -u      # -u: user 当前登录用户
whoami      # 只输出当前登录用户的用户名

 

wc  计算机文件中的行数、单词数和字符数

wc -l /etc/passwd   # -l: line 行数
wc -w /etc/passwd   # -w: word 行数
wc -c /etc/passwd   # -c: char 行数
wc -l ~/code/src/*.cpp  # 依次输出 ~/code/src/*.cpp 的行数与总量
ls -l *.cpp | wc -l # 查看当前目录有多少个 *.cpp 文件

 

cp 复制命令

cp -u   # -u: update 当源文件比目标文件新的时候,才复制
cp -p   # -p: preserve 保持源文件的属性:模式,所有权,时间戳
cp -s   # -s: symbolic-link 软连接,同 ln -s ,ln 默认为硬连接

注:硬连接(Hard Link):硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。

软连接(Symbolic Link):软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

 

mkdir 创建目录

mkdir -pv -m=rwx test/test
# -p: parents 两个作用:1、可以创建需要的多级目录。2、即使目录存在,也不报错
# -v: verbose 创建详情,如果创建成功则输出信息
# -m: mode 创建时赋予权限,同 chmod

 

不同文件的特殊字符标识:可以通过 ls 命令查看,也可以通过 file 命令。

-       # 普通文件,如文本文件,二进制文件等
d       # 目录
l       # 符号连接文件(软连接)
c       # 字符特殊文件,提供对设备不带缓冲的访问,每次访问长度可变。
b       # 块特殊文件,提供对设备带缓冲的访问,每次访问以固定长度为单位进行。
p       # 命名管道,用于进程间通信(IPC)
s       # sockek,用于进程间网络通信

 

chmod 修改权限

chmod 777 src               # 777 分别设置 user\group\other 三者(all)权限,八进制方式,1表示执行,2表示写,4表示读,相加得复合权限,八进制方式只能设置权限,而不能增加或去除权限
chmod a-x src               # =/+/- rwx 用于赋予或增加或去除权限,a 表示 all,也可为 u,g,o ,也可写成 ugo-x,默认不写为 a
chmod u+rwx,g+x,o=rw src    # 同上,可以在一起分别设置
chmod a+x -R src            # 递归修改目录权限
chmod a+x -v src            # 输出修改成功后的权限信息

 

chown 和 chgrp : 修改所有者和所有组

chown -v -R root filename           # 修改所有者 -R 表示递归修改,-v 输出修改结果
chown -v root:root filename         # 修改所有者和所有组
chown -v :root filename             # 只修改所有组,同 chgrp
chgrp -v root filename              # 同上

 

后台进程:

可以在执行命令时,在命令后面加上 & 符号,使其在后台运行。如 make & ,但作业在后台运行一样会将结果输出到屏幕上,干扰工作。可以通过如下方式,把输出重定向到文件:

make -j8 > result 2>&1 &

make -j8 1> /dev/null &     #将标准输出扔掉,将错误输出仍默认输出到终端

另外,对于正在运行的作业,也可以通过 Ctrl+Z 键盘挂起作业,然后通过 bg %jobnumber 来令其在后台运行(相应的,可以使用 fg %jobnumber 令其在前台运行),并可以通过 jobs 命令查看当前挂起和在后台运行的作业。,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

当关闭 shell 窗口时,由于父进程是当前终端 shell 的进程,而一旦父进程退出,则会发送 hangup 信号给所有子进程,子进程收到 hangup 以后也会退出。如果我们要在退出 shell 的时候继续运行进程,则需要使用 nohup 忽略 hangup 信号,或者 setsid 将将父进程设为 init 进程。

但是最好的方式,还是使用 screen  

关于后台进程,参见 http://blog.sina.com.cn/s/blog_3e3be35e0100oi9i.html

 

有两种方法执行shell scripts,一种是新产生一个shell,然后执行相应的shell scripts;一种是在当前shell下执行,不

再启用其他shell。

  新产生一个shell然后再执行scripts的方法是在scripts文件开头加入以下语句

  #!/bin/sh

  一般的script文件(.sh)即是这种用法。这种方法先启用新的sub-shell(新的子进程),然后在其下执行命令。

  另外一种方法就是上面说过的source命令,不再产生新的shell,而在当前shell下执行一切命令。

exec命令在执行时会把当前的shell process关闭,然后换到后面的命令继续执行。系统调用exec是以新的进程去代替原来的进程,但进程的PID保持不变。因此,可以这样认为,exec系统调用并没有创建新的

进程,只是替换了原来进程上下文的内容。原进程的代码段,数据段,堆栈段被新的进程所代替。

exec与system的区别

  (1) exec是直接用新的进程去代替原来的程序运行,运行完毕之后不回到原先的程序中去。

  (2) system是调用shell执行你的命令,system=fork+exec+waitpid,执行完毕之后,回到原先的程序中去。继续执行下面的部分。

总之,如果你用exec调用,首先应该fork一个新的进程,然后exec. 而system不需要你fork新进程,已经封装好了。

详见:http://blog.csdn.net/cyberrusher/article/details/7253385

 

source filename 与 sh filename 及./filename执行脚本的区别在那里呢?source命令也称为"点命令",也就是一个点符号。

1.当shell脚本具有可执行权限时,用sh filename与./filename执行脚本是没有区别得。./filename是因为当前目录没有在PATH中,所有"."是用来表示当前目录的。
2.sh filename 重新建立一个子shell,在子shell中执行脚本里面的语句,该子shell继承父shell的环境变量,但子shell新建的、改变的变量不会被带回父shell,除非使用export。
3.source filename:这个命令其实只是简单地读取脚本里面的语句依次在当前shell里面执行,没有建立新的子shell。那么脚本里面所有新建、改变变量的语句都会保存在当前shell里面。

 

echo 和 printf

echo 默认结尾带换行符(可以通过 -n 参数取消),而 printf 默认结尾不带换行符。

#!/bin/bash
echo Hello,World!       # 不能输出分号,因为分号是命令界定符
echo 'Hello,World!'     # 不能输出变量值,如 $PATH,只会原形即"$PATH"
echo "Hello,World"      # 不能输出 \ 等特殊符号,不过可以使用 set +H 之后改变这一情>况
set +H
echo "Hello,World!"
echo "$PATH"
echo "newline\n\n"      # 仍然是不完美的,会直接输出 \n\n 字符,需要加 -e 参数才能识
别转义字符
echo -e "\e[1;31mThis is red text\e[0m"

# 一般 echo 只用于最简单的输出,对于稍微复杂点的输出,请使用 printf
printf "$PATH\nHello,World!\n"
printf "%s\n%s\n" $PATH Hello,World

 

管道符 program1|program2

表示将前者的标准输出重置为后者的标准输入。 < 和 > 和 >> 也可将输入与输出连接到文件,管道却可以把两个执行中的程序衔接到一起

 

模拟登录脚本:

read -p "login as:" login
printf "$login@"
ifconfig eth0 | sed -n "2,2p" | awk '{printf substr($2,6)}'
printf "'s password:"
stty -echo
read password < /dev/tty
printf '\n'
stty echo

 

pgrep 和 pkill

#!/bin/bash
pgrep -l -u root sshd       # -l: list 显示进程名,-u 指定进程所属用户,可以简写成 pgrep -luroot sshd
pkill -9 -u root yychat     # 等同于 pgrep -uroot yychat | xargs kill -9

 

pmap : 查看进程的内存映像信息

[root@localhost ~]# while true; do pmap -d  27841 | tail -1; sleep 2; done
mapped: 502368K    writeable/private: 64024K    shared: 0K
mapped: 502368K    writeable/private: 64024K    shared: 0K
mapped: 502368K    writeable/private: 64024K    shared: 0K

# mapped 表示该进程映射的虚拟地址空间大小,也就是该进程预先分配的虚拟内存大小,即ps出的vsz
# writeable/private 表示进程所占用的私有地址空间大小,也就是该进程实际使用的内存大小      
# shared 表示进程和其他进程共享的内存大小

 

read: 从键盘上读取

read var                    # 从键盘读取字符串放入 var
read -p "login as:" var     # -p: 提示信息
read -s "password:" var     # -s: 不回显
read -n 2 var               # -n: 读取 n 个字符
read -t 3 var               # -t: 特定时限(秒)
read -d ":" var             # -d: 使用定界符结束输入

 

 IFS: 内部字段分隔符(Internal Field Separator)

data="a,b,c"
oldIFS=$IFS      
IFS=,               # IFS默认值是空白字符(换行符、制表符或空格)
for item in $data
do
    echo Item:$item
done;
IFS=$oldIFS

 

if 语句

read -p "Enter x:" x
read -p "Enter y:" y
if [ $x > $y ]      # 注意 [ ] 与之间的表达式必须要有空格
then
    echo "$x>$y"
elif [ $x -lt $y ]
then
    echo "$x<$y"
else
    echo "$x==$y"
fi

# -eq: ==       # equal             也可以写成 = ,但注意,= 两边必须有空格,如果没有空格,就是赋值
# -ne: !=       # not equal
# -gt: >        # greater than
# -lt: <        # less than
# -ge: >=
# -le: <=

# 简单条件语句的写法:
# [ condition ] && action       # 如果 condition 为真,则执行后面语句
# [ condition ] || action       # 如果 condition 为假,则执行后面语句
# 此外,逻辑与/逻辑或 也可以写成:
# [ condition1 -a condition2 ]  # 逻辑与,或 [ condition1 ] -a [ condition2 ]
# [ condition1 -o condition2 ]  # 逻辑或,或 [ condition1 ] -o [ condition2 ]

# 文件系统相关测试:
# [ -f $file_var ]: 如果给定变量包含正常文件路径或文件名,则返回真
# [ -x $file_var ]: 如果给定变量包含的文件可执行,则返回真
# [ -d $file_var ]: 如果给定变量包含的是目录,则返回值,注:如果这里是 -c/-b/-L,则分别对应字符设备文件、块设备文件、符号链接
# [ -e $file_var ]: 如果给定变量包含的文件存在,则返回值
# [ -r $file_var ]: 如果给定变量包含的文件可读,则返回真,注:如果这里是 -w 表示可写
fpath="/etc/passwd"
if [ -e $fpath ];then
    echo "File exits";
else
    echo "Don't exits";
fi

# -eq: ==       # equal             也可以写成 = ,但注意,= 两边必须有空格,如果没有空格,就是赋值
# -ne: !=       # not equal
# -gt: >        # greater than
# -lt: <        # less than
# -ge: >=
# -le: <=

# 简单条件语句的写法:
# [ condition ] && action       # 如果 condition 为真,则执行后面语句
# [ condition ] || action       # 如果 condition 为假,则执行后面语句
# 此外,逻辑与/逻辑或 也可以写成:
# [ condition1 -a condition2 ]  # 逻辑与,或 [ condition1 ] -a [ condition2 ]
# [ condition1 -o condition2 ]  # 逻辑或,或 [ condition1 ] -o [ condition2 ]

# 文件系统相关测试:
# [ -f $file_var ]: 如果给定变量包含正常文件路径或文件名,则返回真
# [ -x $file_var ]: 如果给定变量包含的文件可执行,则返回真
# [ -d $file_var ]: 如果给定变量包含的是目录,则返回值,注:如果这里是 -c/-b/-L,则分别对应字符设备文件、块设备文件、符号链接
# [ -e $file_var ]: 如果给定变量包含的文件存在,则返回值
# [ -r $file_var ]: 如果给定变量包含的文件可读,则返回真,注:如果这里是 -w 表示可写
fpath="/etc/passwd"
if [ -e $fpath ];then
    echo "File exits";
else
    echo "Don't exits";
fi

# 字符串比较时,最好使用 [[ 和 ]] ,有时采用单中括号可能会有问题
# [[ -n $str ]]: 如果 str 包含的是非空字符串,则返回真
# [[ -z $str ]]: 如果 str 包含的是空字符串,则返回真

# test 用来执行条件检测,有助于过多使用中括号。
if test 3 -gt 1; then
    echo "3>1";
fi

 

 

复合命令:不同命令间用分号隔离,这样会依次执行。

普通用户帐号使用$作为提示符,root帐号使用 # 作为提示符。

 

shell 登录过程:

1、执行 /etc/profile,同时该文件内会遍历执行 /etc/profile.d/ 下的 *.sh 配置文件。

2、执行 .bash_profile (或 ~/.bash_login 或 ~/.profile),同时该文件内会执行  ~/.bashrc,而该文件内又会调用 /etc/bashrc

3、在退出 shell 时,会执行 ~/.bash_logout

 

man 有 8 个不同的指南组成:(我感觉下面说得太乱,需要重新找下资料)

1、命令

2、UNIX 系统调用

3、库,用来存储由 C 程序员使用的与内核无关的函数

4、文件格式,如 /etc/passwd 等文件的格式

5、同样是文件格式

6、包括了玩UNIX所带游戏的指令

7、设备驱动程序

8、系统维护

 

posted @ 2013-09-23 11:17  轻典  阅读(1951)  评论(0编辑  收藏  举报