Xarg 64

0 views
Skip to first unread message

Martha Vanschaick

unread,
Aug 4, 2024, 1:52:17 PM8/4/24
to bupecesscatch
xargsshort for "extended arguments" [1]) is a command on Unix and most Unix-like operating systems used to build and execute commands from standard input. It converts input from standard input into arguments to a command.

Some commands such as grep and awk can take input either as command-line arguments or from the standard input. However, others such as cp and echo can only take input as arguments, which is why xargs is necessary.


A port of an older version of GNU .mw-parser-output .monospacedfont-family:monospace,monospacexargs is available for Microsoft Windows as part of the UnxUtils collection of native Win32 ports of common GNU Unix-like utilities.[2] A ground-up rewrite named wargs is part of the open-source TextTools[3] project. The xargs command has also been ported to the IBM i operating system.[4]


One use case of the xargs command is to remove a list of files using the rm command. POSIX systems have an ARG_MAX for the maximum total length of the command line,[5][6] so the command may fail with an error message of "Argument list too long" (meaning that the exec system call's limit on the length of a command line was exceeded): rm /path/* or rm $(find /path -type f). (The latter invocation is incorrect, as it may expand globs in the output.)


Some implementations of xargs can also be used to parallelize operations with the -P maxprocs argument to specify how many parallel processes should be used to execute the commands over the input argument lists. However, the output streams may not be synchronized. This can be overcome by using an --output file argument where possible, and then combining the results after processing. The following example queues 24 processes and waits on each to finish before launching another.


The xargs command offers options to insert the listed arguments at some position other than the end of the command line. The -I option to xargs takes a string that will be replaced with the supplied input before the command is executed. A common choice is %.


But often people forget this and assume xargs is also line-oriented, which is not the case (per default xargs separates on newlines and blanks within lines, substrings with blanks must be single- or double-quoted).


For Unix environments where xargs does not support the -0 nor the -d option (e.g. Solaris, AIX), the POSIX standard states that one can simply backslash-escape every character:find . -name not\* sed 's/\(.\)/\\\1/g' xargs rm.[8] Alternatively, one can avoid using xargs at all, either by using GNU parallel or using the -exec ... + functionality of find.


One might be dealing with commands that can only accept one or maybe two arguments at a time. For example, the diff command operates on two files at a time. The -n option to xargs specifies how many arguments at a time to supply to the given command. The command will be invoked repeatedly until all input is exhausted. Note that on the last invocation one might get fewer than the desired number of arguments if there is insufficient input. Use xargs to break up the input into two arguments per line:


In addition to running based on a specified number of arguments at a time, one can also invoke a command for each line of input with the -L 1 option. One can use an arbitrary number of lines at a time, but one is most common. Here is how one might diff every git commit against its parent.[9]


The argument separator processing of xargs is not the only problem with using the xargs program in its default mode. Most Unix tools which are often used to manipulate filenames (for example sed, basename, sort, etc.) are text processing tools. However, Unix path names are not really text. Consider a path name /aaa/bbb/ccc. The /aaa directory and its bbb subdirectory can in general be created by different users with different environments. That means these users could have a different locale setup, and that means that aaa and bbb do not even necessarily have to have the same character encoding. For example, aaa could be in UTF-8 and bbb in Shift JIS. As a result, an absolute path name in a Unix system may not be correctly processable as text under a single character encoding. Tools which rely on their input being text may fail on such strings.


One workaround for this problem is to run such tools in the C locale, which essentially processes the bytes of the input as-is. However, this will change the behavior of the tools in ways the user may not expect (for example, some of the user's expectations about case-folding behavior may not be met).


Xargs is a great command that reads streams of data from standard input, then generates and executes command lines; meaning it can take output of a command and passes it as argument of another command. If no command is specified, xargs executes echo by default. You many also instruct it to read data from a file instead of stdin.


5. Xarags also allows you to find and recursively remove a directory, for example the following command will recursively remove DomTerm in the directory Downloads.


12. By default, xargs terminates/delimits items using blank spaces, you can use the -d flag to set the delimiter which may be a single character, a C-style character escape such as \n, or an octal or hexadecimal escape code.


In addition, you can also prompt the user about whether to run each command line and read a line from the terminal, using the -p flag as shown (simply type y for yes or n for no).


I really like this article, I just really felt the need to point out, this article could use some spell checking and general grammar checking. Also, the output of a command is referred to as stdout NOT stdin, stdin would be the keyboard. So you may want to correct that. So you are instructing xargs to act on the output a command that is stdout i.e. the display.


True the output of a command is sent to stdout but when piped to xargs, it considered as std in(please read the xargs man page for more information). In the above examples, we have used the pipe character to enable it to read from standard input, which in this case is the output of another command. We will work on the spell checking and general grammar checking. Thanks once again.


Thank you for taking the time to share your thoughts with us. We appreciate your decision to leave a comment and value your contribution to the discussion. It's important to note that we moderate all comments in accordance with our comment policy to ensure a respectful and constructive conversation.


This pipes the output (stdout)* from find to (stdin of)* grep 'stdlib.h' as text (ie the filenames are treated as text). grep does its usual thing and finds the matching lines in this text (any file names which themselves contain the pattern). The contents of the files are never read.


This constructs a command grep 'stdlib.h' to which each result from find is an argument - so this will look for matches inside each file found by find (xargs can be thought of as turning its stdin into arguments to the given commands)*


Use -type f in your find command, or you will get errors from grep for matching directories. Also, if the filenames have spaces, xargs will screw up badly, so use the null separator by adding -print0 and xargs -0 for more reliable results:


So at that point, you might as well just do find -name stdlib.h. Of course, with -name '*.c' -name stdlib.h, you won't get any output because those patterns can't both match, and find's default behaviour is to AND the rules together.


In general, xargs is used for cases where you would pipe (with the symbol ) something from one command to the other (Command1 Command2), but the output from the first command is not correctly received as the input for the second command.


This typically happens when the second command does not handle data input through Standard In (stdin) correctly (eg: Multiple lines as input, the way the lines are setup, the characters used as input, multiple parameters as input, the data type received as input, etc..). To give you a quick example, test the following:


ls echo - This will not do anything since echo does not know how to handle the input he is receiving. Now in this case if we use xargs it will process the input in a way that can be handled correctly by echo (eg: As a single line of information)


As mentioned in other answers, the reason for using the -print0 argument to find in this scenario and the -0 argument to xargs, is so that filenames with certain characters (e.g. quotes, spaces or even newlines) are still handled correctly.


Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1


They all seem fine when you start with ls grep foo xargs rm. Generalize how many lines get grouped into the output (-L), and generalize command generation (-I). But these quickly tangle into a mess. Command generation assumes only 1 line per output. grouping assumes STDIN is slapped on the end of a line.


If you\u2019re tempted to do 3 things like xargs did. Lie. Down. Wait until the feeling passes. Then, get up see if you can already do what you want with existing tools. For xargs, you can. So, just don\u2019t. It\u2019ll be (infinitely) fast to write, you\u2019ll have feature parity with the original monstrosity, and there won\u2019t be a bugs section about how two features don\u2019t play nice.

3a8082e126
Reply all
Reply to author
Forward
0 new messages