之所以用到命令行参数,关键在于shell脚本需要与运行脚本的人员进行交互。
创新互联建站于2013年成立,是专业互联网技术服务公司,拥有项目做网站、网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元施秉做网站,已为上家服务,为施秉各地企业和个人服务,联系电话:18980820575
bash shell提供了命令行参数添加在命令后面的数据值)、命令行选项修改命令行为的单字符值)和直接读取键盘输入。
1、命令行参数
向shell脚本传递数据的最基本方式是使用命令行参数。
1)读取参数
读取输入的参数的变量为位置参数,位置参数通过标准数字表示,
其中$0为程序名称,$1为第一个参数,$2为第二个参数,依次类推,直到$9为第九个参数。
shell脚本自动将命令行参数赋值给各个位置变量。
同时输入多个参数可以是数值也可以是字符串)时,必须使用空格分隔要想在参数值中包含空格,就必须使用单引号或双引号)
当参数多于9个后,必须在shell脚本内使用大括号将变量括起来,如${10}。从而可以使用任意个参数。
2)读取程序名称
传递给变量$0的字符串实际上是程序的路径根据调用方法决定是相对还是绝对路径)。
使用basename命令可以去掉路径前缀,只获得程序名称名字中不 可以有空格)。
3)测试脚本
当脚本认为应该包含参数,却实际上没有数据时,就会出错。
好的方法是对参数进行检查来保证使用参数前确实存在数据,可以使用-n参数来检查。
例子:if [ –n “$1” ] then .. else .. fi
2、特殊的参数变量
用于跟踪命令行参数
1)参数计数
使用特殊变量$#测试执行脚本时包含的命令行参数个数。脚本中任何位置都可以 使用$#
例子:if [ $# –ne 2 ] 即可测试参数个数
可以使用${!#}来返回最后一个命令行参数当无参数时,$#为0,而${!#}为程序名)
2)获取所有数据
变量$*将命令行中提供的所有参数作为一个单词处理,它将多个参数看成 一个参数。
变量$@将命令行中提供的所有参数作为同一个字符串中的多个单词处理。 允许对其中的值进行迭代一般使用for),分隔开不同参数
3、移位
shift命令能够改变命令行参数的相对位置。默 认将每个参数变量左移一个位置变量$0不变,把$1丢弃,注意不可以恢复了!)
在不清楚参数数目情况下,这是一个迭代参数的好办法。
可以为shift提供一个参数,来实现多位移变化。
4、处理选项
选项是由破折号引导的单个字母,用于更改命令的行为。
1,找出选项
1)处理简单选项
可以使用处理命令行参数相同的方法处理选项,抽取时使用case语句进行判断是否符合选项格式。
2)从参数中分离选项
同时使用选项和参数时,可以使用--指示选项列表的结束。发现--后,shell就知道后面的是普通参数了,停止使用case处理选项。
3)处理带值的选项
选项后紧跟参数值,一种方法是在case中对应选项后使用shift和读后一位参数的方法处理。更好的方法如 下:
2,使用getopt命令
getopt命令在处理选项和参数时非常方便。它对参数进行重新组 织,以便于解析
1)命令格式
getopt可以接受任意形式的选项和参数列表,并自动将它们转换为适当的格式。
命令格式为: getopt options optstring parameters
选项字符串(opstring)用于定义命令行中的有效选项字母,以及哪些选项字母需要参数值。
2)脚本中使用getopt
需要使用set命令将现有的命令行选项和参数替换为getopt命令生成的 格式化形式。
需要将原始脚本命令行参数送给getopt命令,然后将getopt命令输出送给set命令,如下:set – `getopts –q ab:cd “$@”`
但是getopt命令不能很好的处理带有空格的参数值,它将空格解析为参数分隔符,而不是将双引号引起来的两个 值合并成一个参数。解决办法如下:
3)更高级的getopts命令
getopts命令顺序的对现有的shell参数变量进行处理,每调用一次,只处理命令中检测到的参数中的一个。处理完所有参数后,以大于0的退出 状态退出。
非常适宜于在循环中解析所有命令行参数
格式为: getopts optstring variable
$optarg包含需要参数值的选项要使用的值,$optind包含getopts停止处理时在参数列表中的位置。
注意:当getopts处理时,会将选项前的-去掉,所以对应的case中不需要破折号。
好的特性:
1)可以在参数值中包含空格
2)选项字母和参数值中间可以没有空格
3)将在命令行中找到的未定义的选项都绑定为单一的输出——问号
5、标准化选项
有一些字母选项具有标准含义。最好按照标准含义定义选项意义
-a –c –d –e –f –h –i –l –n –o –q –r –s –v- x –y
6、获取用户输入
当需要在执行过程中获得执行脚本人员的输入,使用read命令
1)基本读取
read命令接受标准输入或其他文件描述符输入。读入后将数据放入 一个标准变量中。
-p 允许在read命令行中直接指定一个提示。
可以指定多个变量,也可以不指定将放置在reply环境变量中)
2)计时
使用-t指定一个计时器,计时数满还未输入,read返回一个非0的退出状态。
使用-n指定输入的字符个数,输入达到预定数目时,就自动结束输入
3)默读
使用-s使输入不显示在终端例如输入密码)
4)读取文件
最常用的方法是使用cat命令,并通过管道传给包含read的while语句。
GNU/Linux的命令行选项有两种类型:短选项和长选项,前者以 '-' 作为前导符,后者以 '--' 作为前导符
。比如有一个命令:
$ myprog -a vv --add -b --file a.txt b.txt - -- -e c.txt
在GNU/Linux系统,对这种情况的一种合理解释是:
a是短选项,带一个参数vv;
add是长选项,无参数;
b是短选项,无参数;
file是长选项,带一个参数a.txt;
b.txt是参数;
-是参数,通常表示标准输入,stdin;
--是一个指示符,表明停止扫描参数,其后所有部分都是参数,而不是选项;
-e是参数;
c.txt是参数
为了简化程序设计,有几个库函数可以优雅地分析命令行参数,原型如下:
#include unistd.h
int getopt(int argc, char * const argv[],
const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#define _GNU_SOURCE
#include getopt.h
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
我们先看看用于分析短参数的getopt函数。参数含义如下:
argc, argv是从main函数获取的参数,原样传给getopt;
optstring指示如何分析参数。
关于optstring,还有几点说明:
如果选项带参数,该选项后接冒号,比如上例中optstring为"a:b",指示a带参数,b没有参数;
如果选项带可选参数,该选项后接两个冒号,比如"a::b",表明a可能有参数,也可能没有;
如果optstring的开头字符为':',表明如果指明选项带参数,而实际命令行没有参数时,getopt返回':'而不是'?'(默认情况下返回'?',和无法识别的参数返回一样);
如果optstring的开头字符为'+',表明一但遇到一个无选项参数,马上停止扫描,随后的部分当作参数来解释;
如果optstring的开头字符为'-',表明如果遇到无选项参数,则把它当作选项1(不是字符'1')的参数
该函数每解析完一个选项,就返回该选项字符。
如果选项带参数,参数保存在optarg中。如果选项带可选参数,而实际无参数时,optarg为NULL。
当遇到一个不在optstring指明的选项时,返回字符‘?’。如果在optstring指明某选项带参数而实际没有参数时,返回字符‘?’或者字符‘:’,视optstring的第一个字符而定。这两种情况选项的实际值被保存在optopt中。
当解析错误时,如果opterr为1则自动打印一条错误消息(默认),否则不打印。
当解析完成时,返回-1。
每当解析完一个argv,optind就会递增。如果遇到无选项参数,getopt默认会把该参数调后一位,接着解析下一个参数。如果解析完成后还有无选项的参数,则optind指示的是第一个无选项参数在argv中的索引。
函数getopt_long()的工作方式类似于getopt(),不过它还能接收长选项。在接收长选项之前,我们必须定义个一个结构体数组变量longopts,指明我们希望获取的长选项。
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
含义如下:
name指明长选项的名称;
has_arg指明该选项是否带参数,1为是,0为否,2为可选;
flag指明长选项如何返回,如果flag为NULL,则getopt_long返回val。否则返回0,flag指向一个值为val的变量。如果该长选项没有发现,flag保持不变;
val指明返回的值,或者需要加载到被flag所指示的变量中。
option数组的最后一个元素必须全部填充0.
getopt_long的最后一个参数longindex在函数返回时指向被搜索到的选项在longopts数组中的下标。longindex可以为NULL,表明不需要返回这个值。
getopt_long_only类似于getopt_long,但是它把'-'开头的选项当作长选项来处理。如果该选项与长选项不匹配,而与短选项匹配,则可以作为短选项解析。
在短选项找到的时候,getopt_long和getopt_long_only的表现和getopt一样。如果长选项找到了,如果flag为 NULL,返回val,否则返回0。错误情况的处理和getopt一样,只是返回'?'时还可能是别的情况引起的:选项含糊不明确或者无关参数。
我们拿Linux手册的一个例子来说事。
#include stdio.h /* for printf */
#include stdlib.h /* for exit */
#include getopt.h
int
main (int argc, char **argv) {
int c;
int digit_optind = 0;
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 1, 0, ’c’},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = getopt_long (argc, argv, "abc:d:012",
long_options, option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case ’0’:
case ’1’:
case ’2’:
if (digit_optind != 0 digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case ’a’:
printf ("option a\n");
break;
case ’b’:
printf ("option b\n");
break;
case ’c’:
printf ("option c with value ‘%s’\n", optarg);
break;
case ’d’:
printf ("option d with value ‘%s’\n", optarg);
break;
case ’?’:
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind argc) {
printf ("non-option ARGV-elements: ");
while (optind argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
我们用digit_optind和this_option_optind来跟踪选项012是否在一起,比如选项 -012 和-0 -1 -2 的optind情况是不一样的,前者返回0、1、2时optind相同,而后者optind的值依次大1。
希望你能看懂。。。
方法1.
C/C++语言中的main函数,经常带有参数argc,argv,如下:
int main(int argc, char** argv)
int main(int argc, char* argv[])
这两个参数的作用是什么呢?argc 是指命令行输入参数的个数,argv存储了所有的命令行参数。假如你的程序是hello.exe,如果在命令行运行该程序,(首先应该在命令行下用 cd 命令进入到 hello.exe 文件所在目录) 运行命令为:
hello.exe Shiqi Yu
那么,argc的值是 3,argv[0]是"hello.exe",argv[1]是"Shiqi",argv[2]是"Yu"。
下面的程序演示argc和argv的使用:
怎样通过命令行给linux传输文件,方法如下
一、从服务器下载文件到本机
1、修改文件所属
由于只能下载文件所属为自己的文件,所以要做修改文件所属的操作。
chown hudelei /opt/logs/tomcat/app/tomcat_stk_nm/stk-time.log
2、下载到本机
scp hi@10.10.30.10:/opt/logs/tomcat/app/tomcat_stk_nm/stk-time.log /Users/hvvi/Desktop
3、输入密码
二、上传文件夹到服务器
1、scp -r /Users/hddvvi/Desktop/load hi@10.10.30.10:/opt/logs/tomcat/app/tomcat_stk_nm/
注意:加上 -r,否则会报错:not a regular file
2、输入密码3、文件移动上上层 mv filename.java 。。/
注:本文使用的是mac本机和linux服务器。