分享
 
 
 

设shell自己的隐含变量

王朝other·作者佚名  2008-05-18
窄屏简体版  字體: |||超大  

shell自己的隐含变量,例如$$等, 还有一个隐含变量是记载上一个命令执行成功与

否的,但我想不起来了。那位大虾知道还望告知!或可以在那里找到相关的说明。

Shell Scripts with Multiple Arguments

In a business or personal relationship, having multiple arguments is generally unpleasant and therefore to be avoided. However, in the case of the linux shell, having multiple arguments is downright handy. Of course, in the Linux world, the word argument does not refer to a dispute; instead, it refers to a word appearing on the command line following the name of a program or script. Shell scripts that process multiple arguments afford economy and ease of use; you can simply type a command name once and have that command operate on an entire series of arguments. So this month we'll look at incorporating this capability into a home-brew script.

Shell Arguments

Here's a simple shell script that demonstrates the use of multiple arguments:

echo $1 are not $2

If you create a file named simple that contains this script and then execute it like this:

sh simple dogs cats

you'll see the output:

dogs are not cats

Let's examine how this shell script works. The echo command simply prints the value of each of its arguments. If you read the June Newbies column dealing with environment variables (located online at http://www.linux-mag.com/2001-06/newbies_01.html), you may recognize that $1 and $2 are variable names. They can be recognized as such due to the dollar sign that appears as the first character of each name.

More specifically, $1 and $2 are known as shell variables, because the shell sets their value whenever a shell script or command is invoked. The variable $1 holds the first argument (if any) of the command; the variable $2 holds the second argument (if any) of the command.

So, in the previous example, the variable $1 has the value dogs, and the variable $2 has the value cats. Thus, the output of the echo command is dogs are not cats.

Suppose the script had read:

echo $1 are not $3

Notice that the variable named $2 has been replaced by one named $3. If you issued the command:

sh simple dogs cats birds

you'd see the output:

dogs are not birds

The variable named $3 has the value of the third argument, birds. The value of the second argument, cats, is not referenced by the script.

Ready for a curve ball? Try creating this script:

echo $1 are not $10

Notice in this script that the second variable is $10. If you were to then issue the command:

sh simple dogs cats birds ants flies worms skunks turtles fish ocelots

you'd see the output:

dogs are not dogs0

You probably expected to see:

dogs are not ocelots

The reason for the unexpected output is that the shell defines only nine positional arguments, $1 through $9. The shell interprets the token $10 as $1 followed by the digit zero. Hence, the output is dogs0.

Table One summarizes the shell variables related to arguments, including several variables not yet introduced. Among these is $0, which basically spits back the name of the script or command invoked.

Table One: Shell Arguments

Variable value

$0 The name of the shell script or command.

$1-$9 The indicated positional argument. For example, $1 is the first argument.

$# The number of shell arguments.

$@ The value of each shell argument.

$* The values of all shell arguments.

For example, place the following script in a file named me:

echo $0

Then, issue the command:

sh me

The output will consist of the name of the script file:

me

The value of the shell variable $# is the number of script arguments. For example, place the following script in a file named counter:

echo $#

If you invoke this script like so:

sh counter 1 2 3

you'll see the output 3; if you invoke the script like so:

sh counter 1 2 3 4 5

you'll see the output 5.

The shell variables $@ and $* are quite similar. Each provides the values of the script arguments. However, $@ provides the value of each argument, whereas $* provides a single value that consists of each shell argument, separated by a space. To witness this distinction firsthand, use the counter script given earlier and construct a new script, tester, that references it:

sh counter "$@"

sh counter "$*"

If you invoke the new script like so:

sh tester 1 2 3

you'll see the output:

3

1

The output shows that $@ returns three argument values, whereas $* returns only one.

Recycling Files

Okay, now that we've covered the basics of handling script arguments, let's see if we can do something useful with them.

One Microsoft Windows feature for which linux newbies often yearn is the recycle bin. You can obtain Linux applications that provide this feature, such as Deltrree (see http://migas.mine.nu/en_deltree_index.shtml). However, in the true spirit of Linux, we will create our own.

To do so, let's create a script named del that has these contents:

mkdir -p /tmp/$USER/del 2>/dev/null

mv $1 /tmp/$USER/del

Here's what the script does. The first command, mkdir, creates a subdirectory of /tmp. This is named after the user running the script. The -p argument instructs mkdir to make a second subdirectory within the first one. The second subdirectory is named del, after the name of the script. The del directory is the recycle bin for its associated user.

The redirection, 2>/dev/null, suppresses any error messages generated by mkdir. This is necessary because the second and subsequent times that the script is run, the subdirectories will already exist. Attempting to create an existing directory results in an error message, which is best suppressed in order to avoid confusing the user.

The second command, the mv command, moves the file whose name is given as the first script argument. The file is moved to the directory created by the mkdir command on this, or a previous, invocation of the script.

You can use this script to non-irrevocably delete a file. For instance, suppose you're tired of the file movies. txt. If you issue the command rm movies.txt, the file is gone forever. Instead, you can issue the command del movies.txt, which moves the unwanted file to your recycle bin. Files in the /tmp directory are usually permanently deleted after an interval established by the system administrator. Until a file is deleted, you can recover it simply by using mv to move it out of the /tmp directory tree.

Okay, a few important words and warnings are in order here. First, you won't be able to execute the del script in the simple fashion indicated unless you give yourself execute access to the script and place the script in a directory that's on your execution path. Previous articles in this series include instructions on how to do this. A workaround is to issue the command sh del, where del is the path to the del script.

Second, this script won't allow you to recycle files that you delete via a GUI application, such as GNOME's file manager. The script does its work only if you invoke it.

Third, bear in mind that files don't remain in /tmp indefinitely; at some point, they will be automatically deleted. Several linux distributions use the tmpwatch program to delete temporary files older than 10 days.

Fourth and finally, the del script doesn't distinguish identically named files originally residing in distinct directories. For example, if you delete /x/z by using del, you will overwrite any saved copy of /y/z. You can overcome this limitation with a little extra code, if you like. However, use del at your own risk. I don't plan to respond to e-mails concerning lost files (grin).

Handling More Than Nine Arguments

Because the shell provides only nine variables representing arguments, you might conclude that it's impossible to access a tenth or subsequent argument. However, that'd be a hasty conclusion. The shift command solves this particular problem. When the shell executes the shift command, it discards the value of $1; it then shifts the value of $2 into $1, the value of $3 into $2, and so on. The value of the tenth argument ends up in $9. Here's proof. Place the following script in a file named tener:

shift

echo $9

and execute it like this:

sh tener 1 2 3 4 5 6 7 8 9 10

The output should be the value of the tenth argument, 10.

Handling Many Arguments

As convenient as shell arguments are, the shell cannot infinitely handle many arguments. Early versions of the Unix shell were quite restrictive in this regard. Today's BASH shell is more powerful, but if you attempt to feed the shell 10,000 arguments, you may find that it fails to fully cooperate. As you might expect, it is possible to circumvent this limitation.

One technique is to use xargs, a program that runs a specified command on files whose names appear in the program's input stream. Because the file names are sent via the input stream rather than the command line, this technique escapes limitations that restrict the size of the command line or the number of command-line arguments.

As an example, consider how we might re-implement whatsit using xargs. First, let's use ls to generate a list of files in the current directory and send the list to the standard output device:

ls

Now, let's send that result to the xargs command:

ls | xargs

Next, let's specify an argument telling xargs what operation to perform:

ls | xargs whatis

Finally, let's filter and paginate the output as before:

ls | xargs whatis | grep -v 'nothing appropriate' | more

The result works like the original whatsit except that it won't melt down if the current directory contains many files.

The xargs command interprets several useful options. Table Two summarizes them. One of the most useful of xarg's arguments is --interactive. When this option is specified, xargs prompts for user confirmation before executing the specified command.

Table Two: Options of the xargs Command

Option Definition

--eof=string Specifies that string denotes the end of input. Processing ceases when the specified string is encountered.

--exit Specifies that execution will terminate if --max-chars limit is exceeded.

--help Prints a summary of command options.

--interactive Specifies that the user must confirm each command action.

--max-args=number Specifies the maximum number of arguments used per command line.

--max-chars=number Specifies the maximum number of characters per command line.

--max-lines=number Specifies the maximum number of input lines used per command line.

--max-procs=number Specifies the number of commands that will be simultaneously executed.

--no-run-if-empty Specifies that the command will not be executed if there is no input.

--null Specifies that a null character, rather than whitespace, separates file names on the input stream.

--replace=string Specifies that string found in the command arguments is to be replaced by file names read from the input stream.

--verbose Specifies that each command will be printed before execution.

--version Specifies that xargs should print its version number and terminate.

As an example of using this option, consider the following script:

ls |grep '.*bak'|xargs --interactive --max-lines=1 rm

This script uses ls to list the names of files in the current directory. Then it uses grep to remove lines pertaining to files other than those having names ending with bak. Finally, xargs is used to interactively delete these backup files. The user must respond y in order for a file to be deleted. If you try this example, be sure to do so in a directory that contains no valuable files. A slight error in typing can result in the deletion of many important files.

Winning Arguments

Okay, now you know how to have multiple arguments without ever losing a single one. This should make you the envy of debaters everywhere. Next month, we'll consider conditional statements, which let you construct scripts that make decisions.

Until then, happy arguing!

Debugging Scripts

When writing scripts, it's helpful to be able to see the commands being executed. To do so, you can use the set command. For instance, placing the command:

set -v

as the first line of a script will cause the script to print command lines as they're executed. Another argument of the set command is even more powerful. Placing the command:

set -x

as the first line of a script will also cause the script to print command lines as they're executed. However, the output will also include the expanded values of each command argument.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有