shell记录

执行脚本

  • 作为可执行程序
chmod +x ./test.sh  #使脚本具有执行权限
./test.sh #执行脚本
  • 作为解释器执行
/bin/sh test.sh
/bin/php test.php

变量使用

name='bob'
echo $name
echo "my name id $name"
echo "Hello,"$name"!"
echo ${#name} #输出 4 (长度) string="你本来就很帅"
echo "长度"${#string}
echo ${string:1:4} #从第二个字符开始截取4个字符 echo `expr index "$string" 本来` #查找字符本或来的位置(哪个字母先出现就计算哪个) ##shell数组
array_name=(value0 value1 value2 value3)
echo ${array_name[@]} #@获取数组所有元素
length=${#array_name[@]} #获取数组长度
echo $length
lengthn=${#array_name[2]} #获取第二个元素的长度
echo $lengthn

注释

#----------------------------------
# 这是一个注释
# author:walkingsun
#---------------------------------- # 多行注释
:<<EOF
注释内容...
注释内容...
注释内容...
EOF :<<!
注释内容...
注释内容...
注释内容...
!

shell传递参数

#!/bin/bash

echo "Shell 传递参数实例!";
echo "执行的文件名:$0"; # $0 为执行的文件名
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

执行

./test.sh 1 2 3
参数处理	说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。
如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 $* 与 $@ 区别: 相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。

运算符

## 算数运算符
运算符 说明 举例
+ 加法 `expr $a + $b` 结果为 30。
- 减法 `expr $a - $b` 结果为 -10。
* 乘法 `expr $a \* $b` 结果为 200。
/ 除法 `expr $b / $a` 结果为 2。
% 取余 `expr $b % $a` 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。 ## 关系运算符
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。 ## 布尔运算符
运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。 ## 逻辑运算符
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true ## 字符串运算符
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否为0,不为0返回 true。 [ -n "$a" ] 返回 true。
str 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。 ## 文件测试运算符 操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

echo

echo -e "OK! \n" # -e 开启转义 \n显示换行

echo -e "OK! \c" # -e 开启转义 \c 不换行

echo "It is a test" > myfile                        #显示结果定向到文件

echo `date`                                         #显示命令执行结果

printf

printf  format-string  [arguments...]

模仿c程序库的printf(php也是如此)

printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4s\n" walkingsun boy 150
# %s %c %d %f都是格式替代符
# %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
# %-4.2f 指格式化为小数,其中.2指保留2位小数。

test

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

# 数值测试
参数 说明
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真 # 字符串测试
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真 # 文件测试
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真

流程控制

if ... else ...

if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi    # 查询进程中命令行包含ssh的数量是否大于1,是返回true   -c 统计数量

if ... elseif ...else ... fi

if condition1
then
command1
elif condition2
then
command2
else
commandN
fi

for

for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done

实例:

for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done ## 顺序输出字符串中的字符
for str in 'This is a string'
do
echo $str
done

数字循环

#!/bin/bash  

for((i=1;i<=10;i++));
do
echo $(expr $i \* 3 + 1);
done

while

while condition
do
command
done

实例:

#!/bin/bash
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done

无限循环

while :
do
command
done
或者 while true
do
command
done
或者 for (( ; ; ))

until

until 循环
until 循环执行一系列命令直至条件为 true 时停止。 until 循环与 while 循环在处理方式上刚好相反。 一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。 until 语法格式: until condition
do
command
done

case

case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac

实例

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac

跳出循环

break和continue (同PHP)

esac

需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break。

函数

[ function ] funname [()]

{

    action;

    [return int;]

}

实例:

funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !" # 传参
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
#注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

注意


参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与$*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

输入输出重定向


命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

实例

 who > users   #执行 who 命令,它将命令的完整的输出重定向在用户文件中(users)

重定向深入

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息
command 2 > file    #stderr 重定向到 file

command 2 >> file   #stderr 追加到 file 文件末尾

command > file 2>&1   #stdout 和 stderr 合并后重定向到 file

command < file1 >file2  #stdin 和 stdout 都重定向,command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2

Here Document

command << delimiter
document
delimiter

实例

在命令行中通过 wc -l 命令计算 Here Document 的行数:

$ wc -l << EOF
欢迎来到
菜鸟教程
www.runoob.com
EOF 3 # 输出结果为 3 行
$

/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1

shell文件包含

. filename   # 注意点号(.)和文件名中间有一空格

或

source filename

nohup 退出帐户/关闭终端之后继续运行相应的进程

nohup command > myout.file 2>&1 &

0 – stdin (standard input),1 – stdout (standard output),2 – stderr (standard error) ;
2>&1是将标准错误(2)重定向到标准输出(&1),标准输出(&1)再被重定向输入到myout.file文件中。

& : 指在后台运行

&是指在后台运行,但当用户推出(挂起)的时候,命令自动也跟着退出

sh test.sh &

使命令永久的在后台执行

nohup COMMAND &

实践

这里会记录典型的shell应用场景

系统日志太多,占空间,想清理掉一个月之前的日志,只保留近期一个月的日志

#!/bin/sh
# 清理日志
# author:walkingsun
# test path=/data/app/WindBlog/runtime/logs/ #指定清理目录
timeout=`expr 30 \* 86400` #过期时间(当前设为30天)
systime=`date +%s` #获取当前系统的时间 (秒为单位) files=$(ls $path)
for filename in $files
do
fileuptime=`stat -c %Y $path$filename` #获取文件修改时间(秒)
if [ $[ $systime - $fileuptime ] -gt $timeout ]
then
echo $path$filename
echo `rm -rf $apth$filename`
fi
done

给定一个文件 file.txt,转置它的内容。

你可以假设每行列数相同,并且每个字段由 ' ' 分隔.

示例:

    假设 file.txt 文件内容如下:

    name age
alice 21
ryan 30
应当输出: name alice ryan
age 21 30

解答

#!/bin/bash

awk '{for(i=1;i<=NF;i++){if(NR==1){data[i]=$i}else{data[i]=data[i]" "$i}}}END{for(i=1;i<=NF;i++) print data[i]}' file.txt

给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个 bash 脚本输出所有有效的电话号码。

你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)

你也可以假设每行前后没有多余的空格字符。

示例:

假设 file.txt 内容如下:

987-123-4567

123 456 7890

(123) 456-7890

你的脚本应当输出下列有效的电话号码:

987-123-4567

(123) 456-7890

#!/bin/bash

awk '/^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$/{print $0}' file.txt

写一个 bash 脚本以统计一个文本文件 words.txt 中每个单词出现的频率。

    为了简单起见,你可以假设:

    words.txt只包括小写字母和 ' ' 。
每个单词只由小写字母组成。
单词间由一个或多个空格字符分隔。
示例: 假设 words.txt 内容如下: the day is sunny the the
the sunny is is
你的脚本应当输出(以词频降序排列): the 4
is 3
sunny 2
day 1
#!/bin/bash

awk '{for(i=1;i<=NF;i++){a[$i]=a[$i]+1}}END{for(k in a){print k" "a[k]}}' words.txt |sort -nr -k 2

分表1024张,生成sql脚本

文件 db.sh

#!/bin/bash
start=$1
end=$2
file=$3
echo '' > $file
#for y in {$start..$end};do
for((i=$start;i<$end;i++));do
str=" create table reader_free_click_$i(\n
\`id\` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',\n
\`adid\` varchar(32) NOT NULL DEFAULT '' COMMENT '广告计划id',\n
\`cid\` varchar(100) NOT NULL DEFAULT '' COMMENT '广告创意id',\n
\`imei_md5\` char(32) NOT NULL DEFAULT '' COMMENT '安卓设备识别码的md5',\n
\`mac\` char(32) NOT NULL DEFAULT '' COMMENT 'MAC地址的md5sum',\n
\`androidid\` varchar(40) DEFAULT NULL,\n
\`client_ip\` varchar(40) DEFAULT NULL,\n
\`source\` varchar(32) NOT NULL DEFAULT '' COMMENT '媒体来源',\n
\`timestamp\` bigint(18) NOT NULL DEFAULT '0' COMMENT '点击时间',\n
\`callback\` varchar(2048) NOT NULL DEFAULT '' COMMENT '回调参数',\n
\`channel\` varchar(40) DEFAULT NULL COMMENT '渠道唯一标示',\n
\`change_flag\` tinyint(1) NOT NULL DEFAULT '0' COMMENT '渠道是否变更(0:没有变更; 1:变更过)',\n
\`old_channel\` varchar(50) NOT NULL DEFAULT '' COMMENT '原始日志的渠道名',\n
\`book_id\` int(11) DEFAULT '0',\n
\`created_at\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '插入日期',\n
PRIMARY KEY (\`id\`),\n
UNIQUE KEY \`uk_its\` (\`imei_md5\`,\`timestamp\`,\`source\`)\n
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='免费小说媒体点击数据';\n\n";
echo $str >> $file
done

执行:

sh  db.sh 0 1023 db.sql

shell study的更多相关文章

  1. Shell study note

    td p { margin-bottom: 0in } p { margin-bottom: 0.1in; line-height: 120% } a:link { } 5.1 printenv vi ...

  2. 第17篇 shell编程基础(2)

    shell study 1.Exit StatusIf the command executed successfully (or true), the value of $? is zero. If ...

  3. MongoDB学习笔记二—Shell操作

    数据类型 MongoDB在保留JSON基本键/值对特性的基础上,添加了其他一些数据类型. null null用于表示空值或者不存在的字段:{“x”:null} 布尔型 布尔类型有两个值true和fal ...

  4. 学习 shell脚本之前的基础知识

    转载自:http://www.92csz.com/study/linux/12.htm  学习 shell脚本之前的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写sh ...

  5. xv6的作业翻译——作业1 - shell和系统调用

    Xv6的lecture LEC 1 Operating systems   L1: O/S overview L1:O/S概述   * 6.828 goals 6.828的目标   Understan ...

  6. shell脚本(管理守护进程)

    工作中常常会遇到处理消息队列的消费者进程,这样的进程是一个守护进程,即一个服务.服务通常写个shell脚本来管理,查询服务的status  ,启动start 关闭stop  重启reload.最近在学 ...

  7. linux shell中的特殊符号

    该内容,均来自此网址(http://www.92csz.com/study/linux/12.htm).在下只是把那些命令的截图给去了. 你在学习linux的过程中,也许你已经接触过某个特殊符号,例如 ...

  8. Shell中变量的使用

    1.变量的声明 name="blacksonny" 注意://变量定义时不加$,变量与等号之间不能有空格 变量命名规则: 首个字符必须为字母(a-z,A-Z). 中间不能有空格,可 ...

  9. shell 脚本——判断条件

    在之前的shell语言学习笔记中已经写过shell的几种判断语句及循环语句,也简单的介绍了shell语言判断语句和判断条件.在此再做进一步学习. test命令的测试功能 test命令用于检测系统文件及 ...

随机推荐

  1. Calendar详解

    (在文章的最后,将会介绍Date类,如果有兴趣,可以直接翻到最后去阅读) 究竟什么是一个 Calendar 呢?中文的翻译就是日历,那我们立刻可以想到我们生活中有阳(公)历.阴(农)历之分.它们的区别 ...

  2. 8分钟丨教你玩转 API

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由织云平台团队发表于云+社区专栏 背景 当下,业界越来越多公司在项目架构设计时,会采用微服务架构.微服务架构,可以让我们的产品有更好的扩 ...

  3. vuex中怎么把‘库’中的状态对象赋值给内部对象(三种方法)

    一.通过computed的计算属性直接赋值 import store from '@/store/store' export default{ name: 'count', data(){ retur ...

  4. 每天一道剑指offer-二叉树的下一个结点1

    题目 每天一道剑指offer-二叉树的下一个结点https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&a ...

  5. js加载事件和js函数定义

    一  dom文档树加载完之后执行一个函数 在Dom加载完成后执行函数,下面这三个的作用是一样的,window.onload 是JavaScript的,window.onload是在dom文档树加载完和 ...

  6. C#:ORM--实体框架EF(entity framework)(1)

    本文来自:http://www.cnblogs.com/xuf22/articles/5513283.html 一.什么是ORM ORM(Object-relational mapping),中文翻译 ...

  7. Activiti - 设置会签

    前些天在群里聊工作流和Activiti,群里有人分享了自己的工作流引擎开源项目,大伙纷纷问这问那(比如为什么突然自己搞个process engine.有没有eclipse plugin.能不能绘制流程 ...

  8. C# 之String以及浅拷贝与深拷贝

     一.String到底是值类型还是引用类型 MSDN 中明确指出 String 是引用类型而不是值类型,但 String 表面上用起来却像是值类型,这又是什么原因呢? 首先从下面这个例子入手: //值 ...

  9. JS 重写alert,使之能输出多个参数

    windows._alert = windows.alert; windows.alert = function(){ _alert = (Array.prototype.slice(argument ...

  10. BIO、NIO和AIO的区别

    一:事件分离器 在IO读写时,把 IO请求 与 读写操作 分离调配进行,需要用到事件分离器.根据处理机制的不同,事件分离器又分为:同步的Reactor和异步的Proactor. Reactor模型: ...