我是正常蛇

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
#!/bin/bash

#涉及到的命令:#! whereis cd pwd echo export env unset source

#!指定解释器的位置,此处用/bin/bash作为解释器

whereis bash      #输出bash解释器的位置

cd ./    #改变工作空间 改变环境变量 $PWD
pwd         #查看当前工作空间路径 相当与 echo $PWD
#自建命令与外部命令:
#自建命令是SHELL内置命令:以上基本都是自建命令
#外部命令是一个可执行程序,如find grep 和本例 bash.sh,外部命令执行时会申请子进程,子进程执行完毕后回到父进程继续执行,进入子进程后会拷贝父进程的环境变量,但在子进程中无法通过改变环境变量影响到父进程的环境变量,因此简单的说只有内建命令才能改变环境变量。


export HOME=/etc/    #改变环境变量HOME的值

env -i PATH=./:$PATH bash.sh #-i忽略所有的环境变量,紧接着后面设置新的环境变量PATH,然后运行文件bash.sh
                             #-u可忽略制定的环境变量

source ./bash.sh       #行为模式运行文件,行为模式中遇到外部命令不会新建子进程,而是在当前进程执行外部命令。

a=1
unset a #让a成为空,-f 标记可以让方法成为空

【shell 脚本参数】

$0 - $9 : $0为脚本名,$1 - $9 为参数1 到 9

$* : 以一个字符串显示所以参数

$@:可用于迭代参数的变量,直接打印与$*样子一样

$#: 除开$0 的参数个数

shift :删除参数1,其后的参数左移一位

 

mv:移动或重命名文件或目录,通常跟 参数 i ,否则容易覆盖掉已有的文件

 

 

【管道与重定向】

交互命令行中的标准输入 标准输出 标准错误:

标准输入 和 标准输出都是终端, 标准错误是当命令出错的时候终端显示的内容。

 

重定向:可以用 "<"  改变标准输入  ">" 或 ">>" 改变标准输出

echo "redirect to file" > ./temp.txt    #终端不会成为标准输出,redirect to file会被输出到文件中,文件的原始数据被清空,只保留新的数据。

echo "redirect to file" >> ./temp.txt  #跟>>差不多,只不过是追加数据,即保留原始数据。

cat < ./temp.txt > temp_out.txt    #会将temp.txt中的内容拷贝并覆盖 temp_out.txt的内容。

cat:链接或显示文件, cat File 可将file中的内容输出到标准输出。

 

管道:符号 | 表示管道,管道可以将 "|" 左边的输出作为 "|" 右边的输入

ps -ef | grep "nginx" #打印nginx进程的信息

head -n10 ./temp.txt | grep "redirect"

ps:列举所有当前运行进程的信息

grep: 查询输入中匹配的字符串并打印出对应的一行

head:显示一个文件或多个文件的前几行或前几个字节

 

【特殊文件】

/dev/null : 凡是向该文件进行的标准输出都将作废,凡是将该文作为标准输入的标准输出都将变为空。

/dev/zero: 输入输出均变为0, 大小不变。

/dev/tty  : 若将该文件作为标准输出,则输出会显示到终端显示器上。

read: 读取标准输入中的一行

 

【变量】

shell属于弱类型语言

字符串+整型 = 字符串

null + 整形 = 整形

这里考虑如下代码:

a="123abc"

let " a = $a + 1"

echo $a

按照以往的习惯可能会认为 输出为1或者124,不过shell 可能观察到第一个数为数字,然后会将整行包括 abc 全部当成数字来处理,而默认进制是 10 进制,所以abc无法被识别,会提示 “value too great for base” , 解决方法是在前面加上  14#123abc ,这标识 123abc是14进制的数,所以abc没有超过base,但这样明显违背了coder的本意,所以应尽量避免这种情况。

 

变量的真面目:

通常写的$a,其实际上是${a}的简写。完整的形式实际上还提供了更多的实用功能,如替换和模式匹配

替换:

${varname:-word}  :如果varname存在且非null,则返回varname的值,否则返回word

${varname:=word}  :如果varname存在且非null,则返回varname的值,否则将varname赋值为word,并返回值

${varname:?message} :如果varname存在且非null,则返回varname的值,否则打印message并exit

${varname:+word} : 如果varname存在且非null,则返回word,否则返回null.

模式匹配:

${varname#pattern} : 从开头开始匹配最短的并删除,返回剩下的。

${varname##pattern} : 从开头开始匹配最长的并删除,返回剩下的。

${varname%pattern} : 从结尾开始匹配最短的并删除,返回剩下的。

${varname%%pattern} : 从结尾开始匹配最长的并删除,返回剩下的。

${varname/pattern/string}: 匹配最长的并替换为string,只替换第一个。

${varname//pattern/string}: 匹配最长的并替换为string,替换全部匹配。

 

【方法】

格式

function funcname()
{
    echo "your input is $@"
    exit 0
}

方法的参数不用显示给出,方法中用$1 - $9 或者其他方法调用参数,exit会直接推出程序,return推出方法。

调用直接写方法名,空格后加参数: funcname param1 param2 ...

包含文件用 source filepath+filename

 

【流程控制】

下面是一段处理参数代码,基本用到了所有的流程控制语句。

while [ ! $# = 0 ]
do
    case $1 in
        -f) if [ ! $2 = "" ]
            then
                echo "after -f is $2"
                shift 2
            else
                echo "you should put a value after -f"
                shift
            fi
            ;;
        -d) if [ ! $2 = "" ]
            then
                echo "after -d is $2"
                shift 2
            else
                echo "you should put -d value after -d"
                shift 1
            fi
            ;;
        *) echo "invalid input $1"
            shift
            ;;
    esac
done

 

 【正则】

字符集:

[:alnum:]  // 意思是 alpha + number  等于 [0-9a-zA-Z]

[:alpha:] //字母

[:blank:] //空格和tab

[:digit:]  //数字字符

......

呃,没什么好写的了呢..

 

【文本处理】

先看命令:

sort : 排序文本,并且,可以通过修改参数按照规则对字段排序。

uniq : 将文本中重复的记录去除,并且可以显示重复的情况。

wc   : 统计文本出现的行数,字数以及字符书。

pr 、fmt、fold : 格式化文本输出 , 主要用于处理段落式文本。

head/tail : 分别提取文本的开头和结尾

cut/join : 字段处理,可以对字段进行取出和拼接操作。

tr : 完成简单的文本替换。

 

sort: 行排序

几个重要标记:

-d 设置字典序,忽略以特殊字符开头的行

-n  整数序列

-f   忽略大小写

-u  合并相同行

-t[String]   指定分割符

-k[Number]   指定依照哪一列排序   -t -k连用

 

uniq: 去重或显示重复信息

-c 在输出行前面加上在输入文件中出现的次数。

-d 仅输出重复行

-u 仅输出不重复行

 

wc: 统计

-c 显示字符个数

-w 显示单词个数

-l 显示文本行数

 

fmt / fold 

-w 限制文本宽度

 

head  取开头

-n[number] 指定从开头取的行数

-c[number]  指定从开头取的字节数

 

cut 取字段

-d [string] 指定分割符

-f [number,number.....]  指定获取字段列

 

join 连接字段

-1 [number] 指定以第一个文件哪一列来合并

-2 [number] 指定以第二个文件哪一列来合并

-a[number] 保留number列所有数据,只加入新的数据,有点类似sql中的left join right join

 

tr 字符替换或删除

-s 用string2 替换一个或多个连续的string1

 

【文件操作】

权限:

ls ~

大概会出现如下信息:

drwxr-xr-x  5 louis louis  4096 2012-09-15 15:48 Downloads
drwxrwxr-x  3 louis louis  4096 2012-04-18 20:11 eclipse
-rw-r--r--  1 louis louis   179 2012-04-10 17:13 examples.desktop
-rw-rw-r--  1 louis louis 45819 2012-09-15 13:24 gdq.jpg

从左到右依次是:文件类型&权限位,链接数,所有者,所有者群组,文件大小,修改时间,文件名

文件类型 : d为目录,-为普通文件,d为,l符号链接文件,b块文件等等

权限位: linux权限位有9位,比如Downloads的权限为 rwxr-xr-x ,最开始的rwx为文件创建人的权限,中间的r-x为创建人所在用户组的权限,最后三位r-x为其他用户的权限。

把字符全部替换为1,-替换为0,则得到一个二进制数 111101101,替换成10进制则是755,改权限可以不用写9位字母而直接写十进制就行了。

所有者和所有者群组:所有者为创建人,群组即所有者所在的群,通过chown可以改变所有者,chgrp改变群组,chmod改变9位权限位

文件操作:

touch可以修改文件修改时间

find + xargs 可以用户文件遍历和对文件的批量操作,下面是find的几个例子:

find /etc -name "*rc" -print     #递归找出etc目录下所有文件名最后两个字母为rc的文件

find -perm 777 /etc #递归找etc目录下权限为777的文件

find ~ -type d -print #递归找home目录下的目录文件

find /tmp -newer /tmp/record.txt ! /tmp/login.txt #递归找比record.txt文件新且比login.txt旧的文件

find ~ -name "*sh" | xargx grep "function"  #找home 文件下的所用sh文件,并用他们作为标准输入执行grep指令。

comm,diff 和 vimdiff 比较两个文件的异同。有点像svn。

 

【sed】 

-n 按指示打印

-e [string] 命令

命令中 p  打印, d 隐藏 , s/string/replacement/ 

一些例子:

ll | sed -n -e '/-09-/s/-09-/-08-/p' | sed -n -e 's/[[:blank:]]\+/ /gp'

这里把文件中的创建日期的月份改为08 , 并删除多余的空格,只保留一个空格。

 

 

 

 

 

 

 

 

posted on 2012-09-14 14:00  我是正常蛇  阅读(224)  评论(0)    收藏  举报