0362-0364.html

来自「linux-unix130.linux.and.unix.ebooks130 l」· HTML 代码 · 共 521 行

HTML
521
字号




<HTML>

<HEAD>

<TITLE>Developer.com - Online Reference Library - 0672311739:RED HAT LINUX 2ND EDITION:GNU Project Utilities</TITLE>

<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
<SCRIPT>
<!--
function displayWindow(url, width, height) {
        var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>

 -->




<!-- ISBN=0672311739 //-->

<!-- TITLE=RED HAT LINUX 2ND EDITION //-->

<!-- AUTHOR=DAVID PITTS ET AL //-->

<!-- PUBLISHER=MACMILLAN //-->

<!-- IMPRINT=SAMS PUBLISHING //-->

<!-- PUBLICATION DATE=1998 //-->

<!-- CHAPTER=17 //-->

<!-- PAGES=0351-0372 //-->

<!-- UNASSIGNED1 //-->

<!-- UNASSIGNED2 //-->









<P><CENTER>

<a href="0358-0361.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0365-0367.html">Next</A>

</CENTER></P>



<A NAME="PAGENUM-362"><P>Page 362</P></A>













<P>There is no need to specify filenames to xargs because it reads these from the standard

input, so the xargs command will be

</P>





<!-- CODE SNIP //-->

<PRE>

xargs grep -l foo

</PRE>

<!-- END CODE SNIP //-->











<P>To get a list of files for xargs to give to

grep, use find to list the files in /usr/src/linux

that end in .c:

</P>





<!-- CODE SNIP //-->

<PRE>

find /usr/src/linux -name &quot;*.c&quot;

</PRE>

<!-- END CODE SNIP //-->











<P>Then attach the standard output of find to the standard input of

xargs with a pipe:

</P>





<!-- CODE SNIP //-->

<PRE>

find /usr/src/linux -name &quot;*.c&quot; | xargs grep -l foo

</PRE>

<!-- END CODE SNIP //-->











<P>Finally, tack on a wc -l to get a count and you have

</P>





<!-- CODE SNIP //-->

<PRE>

find /usr/src/linux -name &quot;*.c&quot; | xargs grep -l foo | wc -l

</PRE>

<!-- END CODE SNIP //-->











<P>On my system this took about 29 seconds, which is

considerably faster. The difference becomes even greater when more complex commands are run and the list of files is longer.

</P>









<P>You need to be careful about filenames that contain spaces in them. Many people believe

that spaces are not valid characters in UNIX filenames, but they are, and handling them correctly

is becoming an issue of greater importance because today many machines are able to mount

and read disks from systems that frequently use spaces in filenames.

</P>









<P>I routinely mount Mac HFS disks (Zip, floppy, hard disk) and many files on these disks

have spaces in their filenames. This will confuse

xargs because it uses the newline character (\n)

and the space character as filename delimiters. The GNU version of

xargs provides a pretty good workaround for this problem with the

--null and -0 options, which tell xargs to use the

null character (\0 or \000) as the delimiter. In order to generate filenames that end in

null, find can be given the -print0 option instead of

-print.

</P>









<P>As an illustration, here is an ls of my Mac's Zip Tools disk:

</P>





<!-- CODE SNIP //-->

<PRE>

./              .resource/      Desktop DB*     System Folder/ ../

.rootinfo       Desktop DF*     Utilities/ .finderinfo/    Applications/   Icon:0d*

</PRE>

<!-- END CODE SNIP //-->













<P>Notice that the Desktop DB and the Desktop DF files

have spaces in them, as does the System Folder directory. If I wanted to run through this Zip disk and remove all files that end in

prefs copy, I would normally try

</P>





<!-- CODE SNIP //-->

<PRE>

find /mnt/zip -name &quot;*prefs copy&quot; -print | xargs rm

</PRE>

<!-- END CODE SNIP //-->











<P>However, this won't work because I have a filename with spaces, but if I add

-print0, I can do this with no problems:

</P>





<!-- CODE SNIP //-->

<PRE>

find /mnt/zip -name &quot;*prefs copy&quot; -print0 | xargs rm

</PRE>

<!-- END CODE SNIP //-->











<P>Two other options that are useful for xargs are the

-p option, which makes xargs interactive, and the -n

args option, which makes xargs run the specified command with only

args number of arguments.

</P>



<A NAME="PAGENUM-363"><P>Page 363</P></A>













<P>Some people wonder why the -p option. The reason is that

xargs runs the specified command on the filenames from its standard input, so interactive commands like

cp -i, mv -i, and rm -i don't work right. The -p option solves that problem. In the preceding example, the

-p option would have made the command safe because I could answer yes or no to each file.

So the real command I typed was the following:

</P>





<!-- CODE SNIP //-->

<PRE>

find /mnt/zip -name &quot;*prefs copy&quot; -print0 | xargs -p rm

</PRE>

<!-- END CODE SNIP //-->











<P>Many users frequently ask why xargs should be used when shell command substitution

archives the same results. The real drawback with commands such as

</P>





<!-- CODE SNIP //-->

<PRE>

grep -l foo `find /usr/src/linux -name &quot;*.c&quot;`

</PRE>

<!-- END CODE SNIP //-->











<P>is that if the set of files returned by find is longer than the system's command-line length

limit, the command will fail. The xargs approach gets around this problem because

xargs runs the command as many times as is required, instead of just once.

</P>









<H3><A NAME="ch17_ 11">

Shell Utilities

</A></H3>









<P>The GNU shell utilities are a package of small shell programming utilities. The following

programs are included in the package:

</P>



<TABLE WIDTH="360">

<TR><TD>

basename

</TD><TD>

printenv

</TD></TR>

<TR><TD>

chroot

</TD><TD>

printf

</TD></TR>

<TR><TD>

date

</TD><TD>

pwd

</TD></TR>

<TR><TD>

dirname

</TD><TD>

seq

</TD></TR>

<TR><TD>

echo

</TD><TD>

sleep

</TD></TR>

<TR><TD>

env

</TD><TD>

stty

</TD></TR>

<TR><TD>

expr

</TD><TD>

su

</TD></TR>

<TR><TD>

factor

</TD><TD>

tee

</TD></TR>

<TR><TD>

false

</TD><TD>

test

</TD></TR>

<TR><TD>

groups

</TD><TD>

true

</TD></TR>

<TR><TD>

hostname

</TD><TD>

tty

</TD></TR>

<TR><TD>

id

</TD><TD>

uname

</TD></TR>

<TR><TD>

logname

</TD><TD>

users

</TD></TR>

<TR><TD>

nice

</TD><TD>

who

</TD></TR>

<TR><TD>

nohup

</TD><TD>

whoami

</TD></TR>

<TR><TD>

pathchk

</TD><TD>

yes

</TD></TR>

</TABLE>













<H4><A NAME="ch17_ 12">





Who's Who in GNU

</A></H4>









<P>One of the first things many people do when they log on to a new machine is to see who

else is logged on. The GNU shell utilities provide the

commands who and users to give

</P>



<A NAME="PAGENUM-364"><P>Page 364</P></A>











<P>information about which users are currently logged on and what they are doing. The

users command just prints out a list of names of people who are logged on. The

who command is much more sophisticated.

</P>









<P>In addition to giving information about who is logged on,

who makes it possible to find out how long people have been idle, when they logged on, and if they are allowing other people

to talk. Some of the options that who recognizes are as follows:

</P>



<TABLE WIDTH="360">

<TR><TD>

-H or --heading

</TD><TD>

Prints a heading

</TD></TR>

<TR><TD>

-T, -w, or--mesg

</TD><TD>

Adds user message status as

+, -, or ?

</TD></TR>

<TR><TD>

-i, -u, or --idle

</TD><TD>

Adds user idle time as

HOURS:MINUTES, . (less than a minute), or old (greater than a day)

</TD></TR>

</TABLE>















<P>One of the useful features of who over users is that because

who outputs one user entry per line, it can be used with commands like

grep or sed to process and format its output with ease.

</P>









<H4><A NAME="ch17_ 13">





The id Commands

</A></H4>









<P>The next set of frequently used commands are the

id commands.

</P>









<P>Knowing your own uid and gid and having the ability to determine other users'

uids and gids are very handy skills.

</P>









<P>Almost all users know about the commands whoami and

groups, but many have never heard of id, which encompasses their functionality and adds the ability to determine user

information about other people on the system.

</P>









<P>By default, the id command prints out all the identification information about the

current user. When I run id on my system, I get (as myself)

</P>





<!-- CODE SNIP //-->

<PRE>

uid=500(ranga) gid=100(users) groups=100(users)

</PRE>

<!-- END CODE SNIP //-->











<P>But, I can also run id on my brother's login name:

</P>





<!-- CODE SNIP //-->

<PRE>

id vathsa

</PRE>

<!-- END CODE SNIP //-->











<P>and I get

</P>





<!-- CODE SNIP //-->

<PRE>

uid=501(vathsa) gid=100(users) groups=500(vathsa)

</PRE>

<!-- END CODE SNIP //-->











<P>I could have determined all the preceding information by looking in

/etc/passwd, but id is a much easier way of accomplishing the task.

</P>









<P>In addition, the output of id can be tailored using the following options:

</P>



<TABLE WIDTH="360">

<TR><TD>

-g or --group

</TD><TD>

Prints only the group ID

</TD></TR>

<TR><TD>

-G or --groups

</TD><TD>

Prints only the supplementary groups

</TD></TR>

<TR><TD>

-n or --name

</TD><TD>

Prints a name instead of a number

</TD></TR>

</TABLE>









<P><CENTER>

<a href="0358-0361.html">Previous</A> | <a href="../ewtoc.html">Table of Contents</A> | <a href="0365-0367.html">Next</A>

</CENTER></P>









</td>
</tr>
</table>

<!-- begin footer information -->





</body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?