如何通过Linux指令让Rlinux脚本实例接收数据?

5888人阅读
& & 本文总结如何使用echo命令向文件中写入内容,例如使用echo指令覆盖文件内容,使用echo指令向文件追加内容,使用echo指令往文件中追加制表符。
& & echo向文件中输出内容的基本方法是使用IO重定向指令——“&”,默认情况下echo输出到标准输出中,使用&指令可重定向输出到文件中。
1.echo指令基本用法
【2】输入指令获得帮助
& & sudo echo --help
& & & & 返回内容如下
用法:echo [短选项]... [字符串]...
或:echo 长选项
将 STRING 回显到标准输出。
-n 不尾随换行符
-e 启用解释反斜杠的转义功能
-E 禁用解释反斜杠的转义功能(默认)
--help 显示此帮助信息并退出
--version 显示版本信息并退出
若-e 可用,则以下序列即可识别:
不再产生新的输出
水平制表符
竖直制表符
字节数以八进制数 NNN (1至3位)表示
字节数以十六进制数 HH (1至2位)表示
2.覆盖文件内容
& & 【示例脚本】test.sh
& & 使用&指令覆盖文件原内容并重新输入内容,若文件不存在则创建文件。
#!/bin/bash
echo &Raspberry& & test.txt
& & 【操作过程】
# 修改权限,脚本可执行
chmod u+x test.sh & &
& & 【文件内容】
3.追加文件内容
& & 【示例脚本】test.sh
& & 使用&&指令向文件追加内容,原内容将保存。
#!/bin/bash
echo &Raspberry& & test.txt
echo &Intel Galileo& && test.txt
& & 【操作过程】
# 修改权限,脚本可执行
chmod u+x test.sh & &
& & 【文件内容】
& & 请注意echo指令默认在行尾增加回车(\n),所以此处显示两行。
Intel Galileo
4.输入转移字符
& & 使用-e参数可启用转移字符。下面通过echo指令向文件写入一个JSON数据包。如果不熟悉JSON格式请参考——【】
& & 【示例脚本】test-json.sh
#!/bin/bash
echo -e &{& & test-json.txt
echo -e &\t\&name\&:\&xukai871105\&& && test-json.txt
echo -e &}& && test-json.txt
& & 【说明】
& & 此处用到了两处转移字符,\t制表符,\&双引号。
& & 【操作过程】
# 修改权限,脚本可执行
chmod u+x test-json.sh & &
./test-json.sh &
& & 【文件内容】
& & &&name&:&xukai871105&
5.使用变量
& & 上面的脚本中3处使用了文件名称test-json.txt,如果文件名称需要修改那么就需要修改3处,这样的操作显得麻烦些,为了简化操作可以使用变量简化脚本。
& & 【示例脚本】test-json.sh
#!/bin/bash
FILE=&test-json.txt&
echo -e &{& & $FILE
echo -e &\t\&name\&:\&xukai871105\&& && $FILE
echo -e &}& && $FILE
& & 【操作过程】
# 修改权限,脚本可执行
chmod u+x test-json.sh & &
./test-json.sh &
& & 【文件内容】
& & &&name&:&xukai871105&
& & Linux的技巧还有很多,需要慢慢积累。给自己加个油。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:944743次
积分:11675
积分:11675
排名:第538名
原创:185篇
评论:1095条
所在地: 江苏无锡
(1)(1)(3)(1)(3)(2)(1)(7)(16)(17)(14)(5)(13)(9)(4)(15)(11)(13)(12)(1)(3)(2)(21)(1)(4)(2)(1)(5)(2)(1)《Linux命令行与shell脚本编程大全》 第二十三章 学习笔记 -
- ITeye技术网站
博客分类:
第一部分:Linux命令行第二部分:shell脚本编程基础第三部分:高级shell编程第四部分:高级shell脚本编程主题
第二十三章:使用数据库
MySQL数据库
MySQL客户端界面
mysql命令行参数
禁用自动重新生成哈希表
禁用 出错后的beep声
不使用历史文件
压缩客户端和服务器之间发送的所有消息
指定要用的数据库
执行指定语句并退出
竖直方向显示查询输出,每行一个数据字段
如果有SQL错误产生,继续执行
使能命名命令的使用
指定MySQL服务器主机名(默认为localhost)
用HTML代码显示查询输出
忽略函数名后的空格
结果中不显示列名
忽略语句,除了在命令行上命名的默认数据库的语句
为用户账户提示输入命令
指定网络连接用的TCP端口号
不缓存每条查询结果
显示列输出,不转义
使用安静模式
为本地(localhost)连接指定一个套接字
以表的形式显示输出
在程序退出时显示调试信息、内存以及CPU统计信息
指定登录用户名
只允许指定了键值的UPDATE和DELETE语句
使用详细模式
如果连接没有完成,等待并重试
用XHTML代码显示查询输出
mysql命令不加任何参数,则会使用Linux登录名连接本地的MySQL服务器。
使用-u指定用户名,-p则告诉mysql提示输出相应的密码
$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.
Your MySQL connection id is 47
Server version: 5.1.72-0ubuntu0.10.04.1 (Ubuntu)
Copyright (c) , Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
Type '' or '\h' for help. Type '\c' to clear the current input statement.
mysql使用两种不同类型的命令:
1.特殊的mysql命令
2.标准SQL语句
连接到数据库和服务器
设置SQL语句分隔符
用命令行编辑器编辑命令
将命令发送到MySQL服务器并垂直显示结果
退出mysql程序
将命令发送到MySQL服务器
显示帮助信息
禁用输出分页并将输出发送到STDOUT
不要将输出发送到输出文件
将分页命令设为指定的程序(默认是more)
打印当前命令
修改mysql命令提示符
退出mysql程序(同exit)
重新构建命令补全哈希表
执行指定文件中的SQL脚本
从MySQL服务器提取状态信息
在系统上执行shell命令
将所有输出附加到指定文件中
使用另外一个数据库
切换到另一个字符集
在每条语句之后显示警告消息
nowarnings
不要在每条语句之后显示警告消息
SHOW可以查看数据库信息,比如:
mysql& SHOW DATABASES;
+--------------------+
| Database
+--------------------+
| information_schema |
+--------------------+
2 rows in set (0.00 sec)
也可以查看数据库中的表信息
mysql& USE
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql& SHOW TABLES;
+---------------------------+
| Tables_in_mysql
+---------------------------+
| columns_priv
| general_log
| help_category
| help_keyword
| help_relation
| help_topic
| ndb_binlog_index
| procs_priv
| slow_log
| tables_priv
| time_zone
| time_zone_leap_second
| time_zone_name
| time_zone_transition
| time_zone_transition_type |
+---------------------------+
23 rows in set (0.00 sec)
mysql里面的数据库命令是不区分大小写的,但是习惯是使用大写字母
创建MySQL数据库对象
创建数据库:
CREATE DATABASES +库名
mysql& CREATE DATABASE
Query OK, 1 row affected (0.00 sec)
mysql& SHOW DATABASES;
+--------------------+
| Database
+--------------------+
| information_schema |
+--------------------+
3 rows in set (0.00 sec)
创建用户账户
mysql& GRANT SELECT,INSERT,UPDATE,DELETE ON test.* TO test_user IDENTIFIED by 'pwd';
GRANT SELECT,INSERT,UPDATE,DELETE说明了可以对数据库进行增删改查
ON test.*指定了作用在test数据库上面的所有表(格式为database.table)
TO test_user IDENTIFIED by 'pwd'指定了账户为test_user,如果test_user账户不存在,则自动创建,IDENTIFIED by允许设置默认密码,此处密码为pwd
mysql& GRANT SELECT,INSERT,UPDATE,DELETE ON test.* TO test_user IDENTIFIED by 'pwd';
Query OK, 0 rows affected (0.00 sec)
之后就可以使用新账户登录了
$ mysql test -u test_user -p
Enter password:
Welcome to the MySQL monitor.
Your MySQL connection id is 59
Server version: 5.1.72-0ubuntu0.10.04.1 (Ubuntu)
Copyright (c) , Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
Type '' or '\h' for help. Type '\c' to clear the current input statement.
PostgreSQL数据库
PostgreSQL命令行界面
psql命令行参数
--echo-all
在输出中显示脚本文件中执行的所有SQL行
--no-align
将输出格式设为非对齐模式,数据不显示或格式化的表
执行指定的SQL语句并退出
指定要连接的数据库
--echo-queries
将所有的查询输出到屏幕上
--echo-hidden
将隐藏的psql元命令输出到屏幕上
执行指定文件中的SQL命令并退出
--field-separator
指定在非对齐模式中分开列表数据的字符。默认是逗号
指定远程PostgreSQL服务器的IP地址或主机名
显示服务器上已有的数据库列表并退出
将查询输出重定向到指定文件中
指定要连接的PostgreSQL服务器的TCP端口
将表打印选项设为指定的值
安静模式,不会显示输出消息
--record-separator
将指定字符做为数据行分隔符。默认为换行符
--single-step
在每个SQL查询后 提示继续还是退出
--single-line
指定回车键而不是分号为一个SQL查询的结束
--tuples-only
在表输出中禁用列的头部和尾部
--table-attr
在HTML模式时使用指定的HTML表标签
--username
使用指定的用户名连接PostgreSQL服务器
--variable
将指定变量设成指定值
显示psql版本号并退出
--password
强制命令提示符
--expanded
使能扩展表输出以显示数据行的额外信息
--nopsqlrc
不要运行psql启动文件
显示psql命令行帮助信息并退出
PostgreSQL管理员账户为postgres,而不是root
如果当前Linux登录账户不是postgres,那么需要使用sudo来以postgres账户运行psql
$ sudo -u postgres psql
[sudo] password for su1216:
psql (8.4.17)
Type "help" for help.
postgres=#
提示符#表示已经做为管理员登录psql。
psql使用两种不同类型的命令:
1.Postgre元命令
2.标准SQL语句
Postgre元命令可以方便的获取数据库环境确切信息,还具有psql会话的set功能。
元命令用反斜线标示。
常用的元命令:
\l:列出已有数据库
\c:连接到数据库
\dt:列出数据库中的表
\du列出Postgre的用户
\z:列出表的权限\?:列出所有可用元命令
\h:列出所有可用SQL命令
\q:退出数据库
postgres=# \l
List of databases
| Encoding | Collation |
Access privileges
-----------+----------+----------+-----------+-------------+-----------------------
| postgres | UTF8
| zh_CN.UTF-8 |
template0 | postgres | UTF8
| zh_CN.UTF-8 | =c/postgres
: postgres=CTc/postgres
template1 | postgres | UTF8
| zh_CN.UTF-8 | =c/postgres
: postgres=CTc/postgres
创建PostgreSQL数据库对象
CREATE DATABASE +库名
postgres=# CREATE DATABASE
CREATE DATABASE
postgres=# \l
List of databases
| Encoding | Collation |
Access privileges
-----------+----------+----------+-----------+-------------+-----------------------
| postgres | UTF8
| zh_CN.UTF-8 |
template0 | postgres | UTF8
| zh_CN.UTF-8 | =c/postgres
: postgres=CTc/postgres
template1 | postgres | UTF8
| zh_CN.UTF-8 | =c/postgres
: postgres=CTc/postgres
| postgres | UTF8
| zh_CN.UTF-8 |
postgres=# \c test
psql (8.4.17)
You are now connected to database "test".
连接到test数据库上的时候,psql的提示符变了,显示的是连接的数据库名称
说明:PostgreSQL在数据库增加了一个控制层,称为模式(schema)。
数据库可以有多个模式,每个模式包含多个表。
默认情况下,每个数据库都有一个称为public的模式。上面的例子中使用的就是public模式。
PostgreSQL中用户账户称为登录角色(Login Role)。PostgreSQL会将登录角色和Linux系统用户账户匹配。
所以有两种常用方法来创建登录角色来运行访问PostgreSQL数据库的shell脚本:
1.创建一个和PostgreSQL登录角色对应的特殊Linux账户来运行所有的shell脚本
2.为每个需要运行shell脚本来访问数据库的Linux用户账户创建PostgreSQL账户
CREATE ROLE +名称
test=# CREATE ROLE
CREATE ROLE
这样就建立了一个角色,如果不使用login参数的话,则不允许登录到PostgreSQL服务器,但可以被授予一些权限。这种角色类型称为组角色(group role)。
PostgreSQL不允许将所有权限赋给匹配到表一级的所有数据库对象,需要为每一个新建的表授予权限。
使用数据表
创建数据表
在创建新表前确保用管理员用户账户(MySQL中的root用户,PostgreSQL中的postgres用户)登录来创建表
MySQL和PostgreSQL的数据类型
定长字符串值
变长字符串值
布尔类型true/false值
YYYY-MM-DD格式的日期值
HH:mm:ss格式的时间值
日期和时间值的组合
长字符串值
大的二进制值
使用CREATE TABLE建立表
test=# CREATE TABLE employees (
test(# empid int not null,
test(# lastname varchar(30),
test(# firstname varchar(30),
test(# salary float,
test(# primary key (empid));
CREATE TABLE / PRIMARY KEY will create implicit index "employees_pkey" for table "employees"
CREATE TABLE
test=# \dt
List of relations
--------+-----------+-------+----------
public | employees | table | postgres
在psql中还需要在表一级分配权限。
test=# GRANT SELECT,INSERT,DELETE,UPDATE ON public.employees TO
以postgres登录角色来执行,并连接到test数据库,且必须指定模式名。
插入和删除数据
关于SQL部分,这里不做详细笔记。
mysql& CREATE TABLE employees (
-& empid int not null,
-& lastname varchar(30),
-& firstname varchar(30),
-& salary float,
-& primary key (empid));
Query OK, 0 rows affected (0.08 sec)
mysql& INSERT INTO employees VALUES (1,'Blum', 'Rich', 1234.5);
Query OK, 1 row affected (0.03 sec)
mysql& SELECT * FROM
+-------+----------+-----------+--------+
| empid | lastname | firstname | salary |
+-------+----------+-----------+--------+
| 1234.5 |
+-------+----------+-----------+--------+
1 row in set (0.00 sec)
在脚本中使用数据库
连接到数据库
对于psql:
$ cat psql_connection
#!/bin/bash
psql=`which psql`
sudo -u postgres $psql
$ psql_connection
could not change directory to "/home/su1216/android/source/linux_learned"
psql (8.4.17)
Type "help" for help.
postgres=#
对于mysql:
$ cat mysql_connection
#!/bin/bash
mysql=`which mysql`
$mysql "test" -u "test" -p
$ mysql_connection
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MySQL monitor.
Your MySQL connection id is 38
Server version: 5.1.72-0ubuntu0.10.04.1 (Ubuntu)
Copyright (c) , Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
Type '' or '\h' for help. Type '\c' to clear the current input statement.
执行脚本时,mysql会停下来要求用户输入密码,这个问题可以避免。
下面是一种糟糕的方式,直接将密码放在脚本中明文显示:
$ cat mysql_connection
#!/bin/bash
mysql=`which mysql`
$mysql "test" -u "test" -ptest
-p与密码紧密相连。
另一种解决方案:
mysql使用$HOME/.my.cnf文件来读取特殊的启动命令和设置。
如果没有这个文件,我们自己建立一个即可
$ touch /home/su1216/.my.cnf
$ gedit /home/su1216/.my.cnf
$ chmod 400 /home/su1216/.my.cnf
.my.cnf内容如下
$ cat /home/su1216/.my.cnf
password = test
现在再执行mysql_connection就不会要求输入密码了
向服务器发送命令
1.发送一个命令并退出
2.发送多个命令
对于mysql,可以使用-e选项:
$ cat mysql_test
#!/bin/bash
mysql=`which mysql`
$mysql "test" -u "test" -ptest -e "select * from employees"
输出结果为:
$ mysql_test
+-------+----------+-----------+--------+
| empid | lastname | firstname | salary |
+-------+----------+-----------+--------+
| 1234.5 |
+-------+----------+-----------+--------+
对于psql,可以使用-c选项
发送多条命令可以使用重定向,注意:最后的EOF所在行不能有其他字符串。
$ cat mysql_test
#!/bin/bash
mysql=`which mysql`
$mysql "test" -u "test" -ptest && EOF
返回的结果是原始数据,没有之前的边框。
多条命令的结果之间没有分隔符
$ mysql_test
Tables_in_test
empid lastname firstname salary
1 Blum Rich 1234.5
对于psql也适用,但是返回的结果是有边框的。
$ cat psql_test
#!/bin/bash
psql=`which psql`
sudo -u postgres $psql
输出结果:
$ psql_test
could not change directory to "/home/su1216/android/source/linux_learned"
You are now connected to database "test".
empid | lastname | firstname | salary
-------+----------+-----------+--------
格式化数据
将结果集赋给变量:
#!/bin/bash
mysql=`which mysql`
results=`$mysql "test" -u "test" -Bse 'show databases'`
for result in $results
echo "$result"
其中-B指明了mysql使用批处理模式(禁止了格式化符号)
-s(silent)使得列标题被禁止掉
使用格式化标签
psql和mysql都使用-H来以HTML格式显示结果
$ mysql "test" -u "test" -He 'select * from employees'
&TABLE BORDER=1&&TR&&TH&empid&/TH&&TH&lastname&/TH&&TH&firstname&/TH&&TH&salary&/TH&&/TR&&TR&&TD&1&/TD&&TD&Blum&/TD&&TD&Rich&/TD&&TD&1234.5&/TD&&/TR&&TR&&TD&2&/TD&&TD&Blum&/TD&&TD&Poor&/TD&&TD&321.099&/TD&&/TR&&/TABLE&
mysql还可以以XML格式显示结果
$ mysql "test" -u "test" -Xe 'select * from employees'
&?xml version="1.0"?&
&resultset statement="select * from employees
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&
&field name="empid"&1&/field&
&field name="lastname"&Blum&/field&
&field name="firstname"&Rich&/field&
&field name="salary"&1234.5&/field&
&field name="empid"&2&/field&
&field name="lastname"&Blum&/field&
&field name="firstname"&Poor&/field&
&field name="salary"&321.099&/field&
&/resultset&
转贴请保留以下链接
本人blog地址
浏览: 313930 次
来自: 北京
浏览量:36513
浏览量:80698
小三将军 写道楼主,我想问下你给的Real.tar.gz是什么 ...
这个程序运行的前提是手机root,但你的手机怎么root的呢? ...
赞一个.......
xszconfig 写道你的排版真恶心将就看吧…………………… ...
你的排版真恶心查看:9731|回复:2
#使用命令行参数
#获取用户输入
有时编写的脚本需要能和运行脚本的人员进行交互,bash shell提供了一些方法来从用户处获取数据,这些方法有如下三种:
1- 命令行参数(添加在命令后的参数)
2- 命令行选项(修改命令行为的单字符串)
3- 直接读取键盘输入
1、命令行参数
向shell脚本传递数据最基本的方式就是命令行参数,主要就是说通过一些特殊变量是的bash shell自动把输入的参数赋值给变量才执行脚本。这些变量叫做位置参数,分别有$1为第一个参数、$2为第二个参数、$0为程序名称。。。
1.1、读取参数
如下看个例子就能理解这个位置参数的概念了:
[root@wzp ~]# chmod u+x 1.1test
[root@wzp ~]# cat 1.1test
#!/bin/bash
for (( b=1; b&=$1; b++ ))
&&a=$[ $a * $b ]
echo the factorial of $1 is $a
[root@wzp ~]# ./1.1test 5
the factorial of 5 is 120
[root@wzp ~]# ./1.1test 4
the factorial of 4 is 24
主要来看./xx后面附带的命令行参数,只有一个参数也即为第一个参数很明显赋值为$1,通过for循环计算出累乘结果,所以你输入的第一个参数值改变了,结果也就随着改变。
如果要输入更多的命令行参数,那么每个命令行参数必须使用空格分隔出来,下面看一个例子:
[root@wzp ~]# cat 1.1test
#!/bin/bash
total=$[ $1 * $2 ]
echo the first param is $1
echo the second param is $2
echo the total value is $total
[root@wzp ~]# ./1.1test 2 3
the first param is 2
the second param is 3
the total value is 6
[root@wzp ~]# ./1.1test 4 7
the first param is 4
the second param is 7
the total value is 28
如上脚本很容易理解,我们看到2/3和4/7都分别被赋值给$1和$2,这里就是通过命令行参数之间的空格分开实现的。当然,数值可以给赋值,对于文本字符串也是可以的,如果要将出现空格的连于一体的参数值可以通过单引号或者双引号括起来,这样bash shell就将其视为一个参数值,先来看个例子:
[root@wzp ~]# cat 1.1test
#!/bin/bash
echo hello $1,glad to meet you.
[root@wzp ~]# ./1.1test 51cto gdin
hello 51cto,glad to meet you.
[root@wzp ~]# ./1.1test 'netease corporation'
hello netease corporation,glad to meet you.
对于脚本中没有附带$2变量则把gdin参数忽略了。
还有一点必须说明的:
如果脚本输入的命令参数多于9个,就必须使用大括号把变量括起来,如{10},来看个例子:
[root@wzp ~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the eleventh param is ${11}
echo the total is $total
[root@wzp ~]# ./1.1test 1 2 3 4 5 6 7 8 9 10 11
the tenth param is 10
the eleventh param is 11
the total is 21
对于这样的结果很好理解,只要注意下{10+}这个东东就行了!
1.2、读取程序名称
一开始我就在上面提到程序名称用$0即可表示,Ok,先看个例子:
[root@wzp ~]# chmod u+x 1.2test
[root@wzp ~]# cat 1.2test
#!/bin/bash
echo the name of the program is:$0
[root@wzp ~]# ./1.2test
the name of the program is:./1.2test
[root@wzp ~]# /root/1.2test
the name of the program is:/root/1.2test
很明显,得出的结果不是我们要的,我们只要输出1.2test这个结果。它所传递的变量$0的字符串是程序的完整路径,而不是名称,这里我们可以通过basename命令实现只返回程序名称,把脚本修改成如下:
[root@wzp ~]# cat 1.2test
#!/bin/bash
name=`basename $0`
echo the name of the program is:$name
[root@wzp ~]# ./1.2test
the name of the program is:1.2test
[root@wzp ~]# $HOME/1.2test
the name of the program is:1.2test
呵呵,这下通过basename实现我们要的结果,有点注意的是使用反单引号来给name赋值,否则命令无法生效!
通过基于使用脚本的名称可以实现执行不同功能,下面看个例子:
[root@wzp ~]# cp 1.2test 51cto
[root@wzp ~]# ln -s 1.2test netease
[root@wzp ~]# ls -l 1.2test 51cto netease
-rwxr--r-- 1 root root 179 02-13 11:21 1.2test
-rwxr--r-- 1 root root 179 02-13 11:22 51cto
lrwxrwxrwx 1 root root& &7 02-13 11:22 netease -& 1.2test
[root@wzp ~]# cat 1.2test
#!/bin/bash
name=`basename $0`
if [ $name = &51cto& ]
&&echo $name is a great IT community
elif [ $name = &netease& ]
&&echo $name is a great internet-sp corparation
[root@wzp ~]# ./51cto
51cto is a great IT community
[root@wzp ~]# ./netease
netease is a great internet-sp corparation
上面的例子通过脚本名称实现了不同内容的输出,可知basename好用啦!
脚本是先判断basename,然后根据basename执行函数。
1.3、测试参数
在shell脚本中使用命令行参数要小心,如果执行脚本缺少必要的参数,则会出现报错信息,如下:
[root@wzp ~]# cat 1.1test
#!/bin/bash
total=$[ ${10} + ${11} ]
echo the tenth param is ${10}
echo the elevnth param is ${11}
echo the total is $total
[root@wzp ~]# ./1.1test
./1.1test: line 2: +&&: syntax error: operand expected (error token is & &)
the tenth param is
the elevnth param is
the total is
我们不输入任何命令行参数,则脚本无法执行。
所以,我们可以通过-n这个参数进行检测:
[root@wzp ~]# cat 1.2test
#!/bin/bash
if [ -n &$1& ]
&&echo $1 exists !
&&echo your inputting is wrong
[root@wzp ~]# ./1.2test twentyfour
twentyfour exists !
[root@wzp ~]# ./1.2test
your inputting is wrong
由此可见,通过该方法是检测参数是否存在的好方法。
2、特殊的参数变量
在bash shell中有一些特殊的变量用户跟踪命令行参数。
2.1、参数计数
我们可以使用bash shell提供的特殊变量$#来检测执行脚本时所包含的命令行参数的个数,看如下例子:
[root@wzp ~]# cat 2.1test
#!/bin/bash
echo there were $# parameters supplied.
[root@wzp ~]# chmod u+x 2.1test
[root@wzp ~]# ./2.1test
there were 0 parameters supplied.
[root@wzp ~]# ./2.1test aa bb cc
there were 3 parameters supplied.
所以,$#是一个值得我们记住脑中的好变量!
2.2、获取所有参数
有时候需要获取命令行中的参数,并对它们进行迭代。这里主要通过两个变量来实现对命令行参数的迭代,分别是:
变量$*和变量$@
变量$*将所有参数视为一个单词
变量$@将分别对待每个参数
我们看个例子\(≧▽≦)/
[root@wzp ~]# chmod u+x 2.2test
[root@wzp ~]# cat 2.2test
#!/bin/bash
for param1 in &$*&
&&echo &\$* parameter #$a = $param1&
&&a=$[ $a+1 ]
for param2 in &$@&
&&echo &\$# parameter #$b = $param2&
&&b=$[ $b+1 ]
for param3 in &$#&
&&echo &the total counts = $param3&
&&c=$[ $c+1 ]
[root@wzp ~]# ./2.2test a b c d e f
$* parameter #1 = a b c d e f
$# parameter #1 = a
$# parameter #2 = b
$# parameter #3 = c
$# parameter #4 = d
$# parameter #5 = e
$# parameter #6 = f
the total counts = 6
通过一个for循环迭代特殊变量,充分体现出[email=$*$@$]$*$@$[/email]#三个特殊变量用途!
bash shell提供了一个工具叫shift命令,实现改变命令行参数的相对位置
默认将每个参数变量左移一位。即为,$3的值移动给变量$2($n+1-&$n),而变量$1则被丢弃,当然,$0这个程序名称没变。下面看个例子:
[root@wzp ~]# cat 3test
#!/bin/bash
while [ -n &$1& ]
echo &parameter #$count = $1&
count=$[ $count + 1 ]
[root@wzp ~]# chmod u+x 3test
[root@wzp ~]# ./3test 51cto emc linux rac
parameter #1 = 51cto
parameter #2 = emc
parameter #3 = linux
parameter #4 = rac
每测试一个参数,使用shift命令将参数移前一位,所以通过while循环即使得每个参数都变成$1被循环下去显示出来。当然,我们可以指定shift的位数,而不是默认的一位。看如下例子:
[root@wzp ~]# cat 3test
#!/bin/bash
echo &the original parameter : $*&
echo &the new shift parameter is : $1&
[root@wzp ~]# ./3test aa bb cc dd ee
the original parameter : aa bb cc dd ee
the new shift parameter is : dd
指定位数为3后,aa bb cc则被忽略了,直接把dd当成$1.
4、处理选项
选项是有破折号引导的单个字母,它更改命令的行为。如下罗列一些标准化选项:
**********************************************
选项& && && && && && &描述
-a& && && && & 实现所有对象
-c& && && && & 生成计数
-d& && && && & 指定目录
-e& && && && & 展开对象
-f& && && && & 指定读取数据的文件
-h& && && && & 显示命令的帮助信息
-i& && && && & 忽略大小写
-l& && && && & 生成长格式的输出
-n& && && && & 使用非交互式(批量)模式
-o& && && && & 指定一个输出文件来重定向输出
-q& && && && & 以quite模式退出
-r& && && && & 递归处理目录和文件
-s& && && && & 以silent模式执行
-v& && && && & 生成verbose模式
-x& && && && & 排除和拒绝
-y& && && && & 设置所有提问回答为yes
**********************************************
4.1、处理简单选项
先来看一个例子:
[root@wzp ~]# cat 4test
#!/bin/bash
while [ -n &$1& ]
case &$1& in
-a) echo &the -a option exists&;;
-b) echo &the -b option exists&;;
-c) echo &the -c option exists&;;
*) echo &the '$1' is not an option &;;
[root@wzp ~]# ./4test -a -b -c -d -e
the -a option exists
the -b option exists
the -c option exists
the '-d' is not an option
the '-e' is not an option
通过case语句循环判断各个选项,并且通过shift灵活移动选项变量。
4.2、从参数中分离选项
执行shell脚本经常会遇到使用选项又需要使用参数的情况。在linux中的标准方式是通过特殊字符码(--,双破折号)将二者分开,表示说当这个脚本程序发现双破折号后,就自动把剩余的命令行视为参数,而不再是选项了,如下看个例子:
[root@wzp ~]# cat 4test
#!/bin/bash
while [ -n &$1& ]
case &$1& in
-a) echo &the -a option exists&;;
-b) echo &the -b option exists&;;
-c) echo &the -c option exists&;;
*) echo &the '$1' is not an option &;;
for param in $@
&&echo &parameter #$count:$param&
&&count=$[ $count + 1 ]
[root@wzp ~]# ./4test -a -c -f -- -b test
the -a option exists
the -c option exists
the '-f' is not an option
parameter #1:-b
parameter #2:test
如上先通过while循环,把满足条件的选项显示出来,不满足条件的选项也显示出,并说明 is not an option ,当使用--把剩下的被脚本识别为参数的命令行则通过break跳出循环,并且在shift作用下置位成$1,然后在for循环下逐一显示出来,表示现实出来的即为参数,而非选项!
如上的脚本得仔细分析,不然很容易出错。
如果不通过双破折号隔离,如下的结果也是我们想象之中的:
[root@wzp ~]# ./4test -a -c -f -b test
the -a option exists
the -c option exists
the '-f' is not an option
the -b option exists
the 'test' is not an option
完全是while循环的判断,没法跳出来执行for循环。
5、获取用户输入
有时在脚本执行过程中需要询问一个问题并等待执行脚本的人员应答,bash shell提供的read命令可以实现这一需求。
5.1、基本读取
read命令接受标准输入(键盘输入),如下示例:
[root@wzp ~]# chmod u+x 5.1test
[root@wzp ~]# cat 5.1test
#!/bin/bash
echo -n &please input your name:&
echo &hello $name, welcome to IT website&
[root@wzp ~]# ./5.1test
please input your name:twentyfour
hello twentyfour, welcome to IT website
通过一个-n选项使得脚本执行输入不用换行显示。
如上通过echo显示结果,实际上可以直接通过read命令在-p选项下直接把输入的内容附加给后面指定的变量,如下例子,效果跟上面完全一样:
[root@wzp ~]# cat 5.1test
#!/bin/bash
read -p &please input your name:& name
echo &hello $name, welcome to IT website&
[root@wzp ~]# ./5.1test
please input your name:CCIE
hello CCIE, welcome to IT website
所以,我们更多可以采用这种方法。
如上的两个方法,我们都是把输入的值赋给了变量name,实际上我们可以不使用这个变量name。这么一来,read命令会把输入的命令赋给一个环境变量REPLY,先来看一个效果:
[root@wzp ~]# read
the content will be sent to \$REPLY
[root@wzp ~]# echo $REPLY
the content will be sent to $REPLY
我使用\把变量转义不被识别,在read命令下输入的内容将被缓存赋给环境变量$REPLY,这下再来看个例子:
[root@wzp ~]# cat 5.1test
#!/bin/bash
read -p &please input your name:&
echo &hello $REPLY, welcome to IT website&
[root@wzp ~]# ./5.1test
please input your name:IBM
hello IBM, welcome to IT website
很明显,这个例子跟如上的很接近,但是这个脚本没使用name变量,所以我输入的IBM被系统赋给了环境变量$REPLY。
如上我们可以通过read命令实现交互性的操作,但是假如没有执行脚本的人员操作,脚本则无法自动运行下去。这个时候就可以使用-t选项指定一个计时器,表示等待时间段(单位为秒),如果超过指定的时间,read命令将返回一个非零退出状态,通过判断语句则使脚本可以自动跳过运行下去,我们先看一个例子:
[root@wzp ~]# chmod u+x 5.2test
[root@wzp ~]# cat 5.2test
#!/bin/bash
if read -t 5 -p &please input your name:&
&&echo &hello $REPLY, welcome to come back here&
&&echo &sorry , you are too slow &
[root@wzp ~]# ./5.2test
please input your name:twentyfour
hello twentyfour, welcome to come back here
[root@wzp ~]# ./5.2test
please input your name:sorry , you are too slow
如上通过-t 5是的输入超过5秒则跳到else的判断结果,有点需要注意就是-p必须放置在-t的后面,否则报错!如上我没有任何输入,超过5秒,则脚本返回了sorry , you are too slow的内容。
到这里还有一个挺经典的-n选项不得不提,除了如上输入时间计时,read还可以通过添加-n选项计数输入的字符。等输入的字符达到预定数目时就自动退出,这里借助case看一个例子:
[root@wzp ~]# cat 5.2test
#!/bin/bash
read -n1 -p &do you want to continue [Y/N]?&
case $REPLY in
Y | y) echo
& && && & echo &fine ,continue on ..&;;
N | n) echo
& && && & echo &OK, goodbye...&;;
[root@wzp ~]# ./5.2test
do you want to continue [Y/N]?y
fine ,continue on ..
[root@wzp ~]# ./5.2test
do you want to continue [Y/N]?N
OK, goodbye...
如上-n后面是数字1,表示read命令接收到一个字符就退出,所以输入Y/N后不用回车就马上执行下去了。这里出现了两个echo,主要是使得结果换行显示,更显人性化。还有就是通过|符号识别大小写,也是人性化。
有时候需要脚本用户进行输入,但输入的数据不显示出来,比如像password的输入。这里可以借用read命令下的-s选项,使得输入的数据颜色跟背景颜色一致,实现不显示数据的效果,看如下例子:
[root@wzp ~]# cat 5.3test
#!/bin/bash
read -s -p &please input your passwd:&
echo your passwd is $REPLY
[root@wzp ~]# chmod u+x 5.3test
[root@wzp ~]# ./5.3test
please input your passwd:your passwd is aaa
[root@wzp ~]# ./5.3test
please input your passwd:your passwd is 51cto
哈哈,这不失为一个非常棒的选项。还有,别以为数据颜色跟背景颜色一样后,你可以通过数据把数据选上而显示出来,linux命令行下输入的数据不占位,压根无法让你选上!
5.4、读取文件
read命令可以读取linux系统上存储的文件数据,每调用一次read命令,都会去读取一行文本(注意,是一行,不是整个文件内容),当read命令读完的文本内容将以非零状态退出。借用while命令看一个例子:
[root@wzp ~]# cat 5.4test
#!/bin/bash
cat 51cto.test | while read line
echo &LINE $count : $line&
count=$[ $count + 1 ]
[root@wzp ~]# cat 51cto.test
aaaaaaaaaa
bbbbbbbbbb
cccccccccc
[root@wzp ~]# ./5.4test
LINE 1 : aaaaaaaaaa
LINE 2 : bbbbbbbbbb
LINE 3 : cccccccccc
这里的51cto.test跟脚本文件放置同一个目录,当然最后就把要读取的文件以绝对路径写入脚本防止脚本读取不到。while命令使用read不断循环读取文件51cto.test中每一行,然后显示出来,直到read读取完后以非零状态退出而结束!
知道先锋队
好文。学习了。:ldw13:
学习了!!!

我要回帖

更多关于 linux shell脚本 的文章

 

随机推荐