📄 library_9.html
字号:
char *buffer = xmalloc (length); (void) regerror (errcode, compiled, buffer, length); return buffer;}</PRE><P><A NAME="IDX406"></A><A NAME="IDX407"></A><H2><A NAME="SEC103" HREF="library_toc.html#SEC103" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC103">Shell-Style Word Expansion</A></H2><P><DFN>Word expansion</DFN> means the process of splitting a string into <DFN>words</DFN> and substituting for variables, commands, and wildcardsjust as the shell does.<P>For example, when you write <SAMP>`ls -l foo.c'</SAMP>, this string is splitinto three separate words---<SAMP>`ls'</SAMP>, <SAMP>`-l'</SAMP> and <SAMP>`foo.c'</SAMP>.This is the most basic function of word expansion.<P>When you write <SAMP>`ls *.c'</SAMP>, this can become many words, becausethe word <SAMP>`*.c'</SAMP> can be replaced with any number of file names.This is called <DFN>wildcard expansion</DFN>, and it is also a part ofword expansion.<P>When you use <SAMP>`echo $PATH'</SAMP> to print your path, you are takingadvantage of <DFN>variable substitution</DFN>, which is also part of wordexpansion.<P>Ordinary programs can perform word expansion just like the shell bycalling the library function <CODE>wordexp</CODE>.<P><H3><A NAME="SEC104" HREF="library_toc.html#SEC104" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC104">The Stages of Word Expansion</A></H3><P>When word expansion is applied to a sequence of words, it performs thefollowing transformations in the order shown here:<P><OL><A NAME="IDX408"></A><LI><DFN>Tilde expansion</DFN>: Replacement of <SAMP>`~foo'</SAMP> with the name ofthe home directory of <SAMP>`foo'</SAMP>.<P><LI>Next, three different transformations are applied in the same step,from left to right:<P><UL><A NAME="IDX409"></A><A NAME="IDX410"></A><LI><DFN>Variable substitution</DFN>: The substitution of environment variablesfor references such as <SAMP>`$foo'</SAMP>.<P><A NAME="IDX411"></A><LI><DFN>Command substitution</DFN>: Replacement of constructs such as <SAMP>``cat foo`'</SAMP> or <SAMP>`$(cat foo)'</SAMP> with the output from the innercommand.<P><A NAME="IDX412"></A><LI><DFN>Arithmetic expansion</DFN>: Replacement of constructs such as<SAMP>`$(($x-1))'</SAMP> with the result of the arithmetic computation.</UL><P><A NAME="IDX413"></A><LI><DFN>Field splitting</DFN>: subdivision of the text into <DFN>words</DFN>.<P><A NAME="IDX414"></A><LI><DFN>Wildcard expansion</DFN>: The replacement of a construct such as <SAMP>`*.c'</SAMP>with a list of <SAMP>`.c'</SAMP> file names. Wildcard expansion applies to anentire word at a time, and replaces that word with 0 or more file namesthat are themselves words.<P><A NAME="IDX415"></A><A NAME="IDX416"></A><LI><DFN>Quote removal</DFN>: The deletion of string-quotes, now that they havedone their job by inhibiting the above transformations when appropriate.</OL><P>For the details of these transformations, and how to write the constructsthat use them, see <CITE>The BASH Manual</CITE> (to appear).<P><H3><A NAME="SEC105" HREF="library_toc.html#SEC105" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC105">Calling <CODE>wordexp</CODE></A></H3><P>All the functions, constants and data types for word expansion aredeclared in the header file <TT>`wordexp.h'</TT>.<P>Word expansion produces a vector of words (strings). To return thisvector, <CODE>wordexp</CODE> uses a special data type, <CODE>wordexp_t</CODE>, whichis a structure. You pass <CODE>wordexp</CODE> the address of the structure,and it fills in the structure's fields to tell you about the results.<P><A NAME="IDX417"></A><U>Data Type:</U> <B>wordexp_t</B><P>This data type holds a pointer to a word vector. More precisely, itrecords both the address of the word vector and its size.<P><DL COMPACT><DT><CODE>we_wordc</CODE><DD>The number of elements in the vector.<P><DT><CODE>we_wordv</CODE><DD>The address of the vector. This field has type <CODE>char **</CODE>.<P><DT><CODE>we_offs</CODE><DD>The offset of the first real element of the vector, from its nominaladdress in the <CODE>we_wordv</CODE> field. Unlike the other fields, thisis always an input to <CODE>wordexp</CODE>, rather than an output from it.<P>If you use a nonzero offset, then that many elements at the beginning ofthe vector are left empty. (The <CODE>wordexp</CODE> function fills them withnull pointers.)<P>The <CODE>we_offs</CODE> field is meaningful only if you use the<CODE>WRDE_DOOFFS</CODE> flag. Otherwise, the offset is always zeroregardless of what is in this field, and the first real element comes atthe beginning of the vector.</DL><P><A NAME="IDX418"></A><U>Function:</U> int <B>wordexp</B> <I>(const char *<VAR>words</VAR>, wordexp_t *<VAR>word-vector-ptr</VAR>, int <VAR>flags</VAR>)</I><P>Perform word expansion on the string <VAR>words</VAR>, putting the result ina newly allocated vector, and store the size and address of this vectorinto <CODE>*<VAR>word-vector-ptr</VAR></CODE>. The argument <VAR>flags</VAR> is acombination of bit flags; see section <A HREF="library_9.html#SEC106" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_9.html#SEC106">Flags for Word Expansion</A>, for details ofthe flags.<P>You shouldn't use any of the characters <SAMP>`|&;<>'</SAMP> in the string<VAR>words</VAR> unless they are quoted; likewise for newline. If you usethese characters unquoted, you will get the <CODE>WRDE_BADCHAR</CODE> errorcode. Don't use parentheses or braces unless they are quoted or part ofa word expansion construct. If you use quotation characters <SAMP>`'"`'</SAMP>,they should come in pairs that balance.<P>The results of word expansion are a sequence of words. The function<CODE>wordexp</CODE> allocates a string for each resulting word, thenallocates a vector of type <CODE>char **</CODE> to store the addresses ofthese strings. The last element of the vector is a null pointer.This vector is called the <DFN>word vector</DFN>.<P>To return this vector, <CODE>wordexp</CODE> stores both its address and itslength (number of elements, not counting the terminating null pointer)into <CODE>*<VAR>word-vector-ptr</VAR></CODE>.<P>If <CODE>wordexp</CODE> succeeds, it returns 0. Otherwise, it returns oneof these error codes:<P><DL COMPACT><DT><CODE>WRDE_BADCHAR</CODE><DD>The input string <VAR>words</VAR> contains an unquoted invalid character suchas <SAMP>`|'</SAMP>.<P><DT><CODE>WRDE_BADVAL</CODE><DD>The input string refers to an undefined shell variable, and you used the flag<CODE>WRDE_UNDEF</CODE> to forbid such references.<P><DT><CODE>WRDE_CMDSUB</CODE><DD>The input string uses command substitution, and you used the flag<CODE>WRDE_NOCMD</CODE> to forbid command substitution.<P><DT><CODE>WRDE_NOSPACE</CODE><DD>It was impossible to allocate memory to hold the result. In this case,<CODE>wordexp</CODE> can store part of the results--as much as it couldallocate room for.<P><DT><CODE>WRDE_SYNTAX</CODE><DD>There was a syntax error in the input string. For example, an unmatchedquoting character is a syntax error.</DL><P><A NAME="IDX419"></A><U>Function:</U> void <B>wordfree</B> <I>(wordexp_t *<VAR>word-vector-ptr</VAR>)</I><P>Free the storage used for the word-strings and vector that<CODE>*<VAR>word-vector-ptr</VAR></CODE> points to. This does not free thestructure <CODE>*<VAR>word-vector-ptr</VAR></CODE> itself--only the otherdata it points to.<P><H3><A NAME="SEC106" HREF="library_toc.html#SEC106" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC106">Flags for Word Expansion</A></H3><P>This section describes the flags that you can specify in the <VAR>flags</VAR> argument to <CODE>wordexp</CODE>. Choose the flags you want,and combine them with the C operator <CODE>|</CODE>.<P><DL COMPACT><DT><CODE>WRDE_APPEND</CODE><DD>Append the words from this expansion to the vector of words produced byprevious calls to <CODE>wordexp</CODE>. This way you can effectively expandseveral words as if they were concatenated with spaces between them.<P>In order for appending to work, you must not modify the contents of theword vector structure between calls to <CODE>wordexp</CODE>. And, if you set<CODE>WRDE_DOOFFS</CODE> in the first call to <CODE>wordexp</CODE>, you must alsoset it when you append to the results.<P><DT><CODE>WRDE_DOOFFS</CODE><DD>Leave blank slots at the beginning of the vector of words.The <CODE>we_offs</CODE> field says how many slots to leave.The blank slots contain null pointers.<P><DT><CODE>WRDE_NOCMD</CODE><DD>Don't do command substitution; if the input requests command substitution,report an error.<P><DT><CODE>WRDE_REUSE</CODE><DD>Reuse a word vector made by a previous call to <CODE>wordexp</CODE>.Instead of allocating a new vector of words, this call to <CODE>wordexp</CODE>will use the vector that already exists (making it larger if necessary).<P><DT><CODE>WRDE_SHOWERR</CODE><DD>Do show any error messages printed by commands run by command substitution.More precisely, allow these commands to inherit the standard error outputstream of the current process. By default, <CODE>wordexp</CODE> gives thesecommands a standard error stream that discards all output.<P><DT><CODE>WRDE_UNDEF</CODE><DD>If the input refers to a shell variable that is not defined, report anerror.</DL><P><H3><A NAME="SEC107" HREF="library_toc.html#SEC107" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_toc.html#SEC107"><CODE>wordexp</CODE> Example</A></H3><P>Here is an example of using <CODE>wordexp</CODE> to expand several stringsand use the results to run a shell command. It also shows the use of<CODE>WRDE_APPEND</CODE> to concatenate the expansions and of <CODE>wordfree</CODE>to free the space allocated by <CODE>wordexp</CODE>.<P><PRE>intexpand_and_execute (const char *program, const char *options){ wordexp_t result; pid_t pid int status, i; /* Expand the string for the program to run. */ switch (wordexp (program, &result, 0)) { case 0: /* Successful. */ break; case WRDE_NOSPACE: /* If the error was <CODE>WRDE_NOSPACE</CODE>, then perhaps part of the result was allocated. */ wordfree (&result); default: /* Some other error. */ return -1; } /* Expand the strings specified for the arguments. */ for (i = 0; args[i]; i++) { if (wordexp (options, &result, WRDE_APPEND)) { wordfree (&result); return -1; } } pid = fork (); if (pid == 0) { /* This is the child process. Execute the command. */ execv (result.we_wordv[0], result.we_wordv); exit (EXIT_FAILURE); } else if (pid < 0) /* The fork failed. Report failure. */ status = -1; else /* This is the parent process. Wait for the child to complete. */ if (waitpid (pid, &status, 0) != pid) status = -1; wordfree (&result); return status;}</PRE><P>In practice, since <CODE>wordexp</CODE> is executed by running a subshell, itwould be faster to do this by concatenating the strings with spacesbetween them and running that as a shell command using <SAMP>`sh -c'</SAMP>.<P><P>Go to the <A HREF="library_8.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_8.html">previous</A>, <A HREF="library_10.html" tppabs="http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_10.html">next</A> section.<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -