IBM Support

Process Environment and Arguments (ARG/ENV)

Question & Answer


Question

This document describes a process's environment and argument list, and why execution of some processes fails with an "Argument list too long" error. The document also explains how to increase the ARG/ENV system limit to avoid this error.

Answer


Introduction

All Unix processes are passed an environment and arguments when they are created by the operating system through an exec system function. The environment is a list of environment variables inherited from the parent process that is executing an exec function, and arguments are a list of data values passed to a new process. The environment and argument list are copied into a block of memory allocated for each process. The size of the environment and number and size of arguments varies by process , but AIX imposes an upper limit in bytes on the size of the memory and this limit will be used by every new process created on the system.  This limit, called ARG/ENV or ncargs, can be adjusted using smitty or the chdev command. If the limit is too low, some commands may fail with an error such as, Argument/Parameter list too long.  While not insignificant, this memory overhead is usually less of a concern on modern systems with many gigabytes of memory. Even so, some administrators will want to keep this limit as low as possible to conserve memory. This document will explain how to estimate the amount of memory needed for process environment and arguments.

What is the Process Environment?

The environment is simply a list of environment variables. Every process inherits the list of environment variables exported by the parent process, and the process may optionally add its own variables to this list. An environment variable contains a variable length string of characters. For example, PATH is a system variable exported in /etc/environment that contains a list of directories that is used by the shell to search for binary executable files when attempting to execute a program.

What is the Size of the Environment List?

The size in bytes of the environment list is the total number of characters in all variable names, plus the = assignment characters, plus the number of characters in the variable contents. Also included is a delimiter character, such as a space or line feed character, at the end of each variable. Consider the following small, example environment.
 
$ env
MANPATH=/usr/share/man:/usr/local/share/man:/usr/X11/man
TERM=xterm-color
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

The size of this environment will be the number of characters in each variable name, plus the three = characters, plus the number of characters in the content of each variable, plus three delimiter characters for the three variables. Using the wc -c command, we see the size is 137 bytes.
 
$ env | wc -c
137
Note: Sizes assume the use of character sets such as ASCII that represent one character with one byte.

What are Process Arguments?

To help explain arguments, we will use the ls command as an example. The ls command can be used with no options, in which case the number of arguments will be one. The reason the number is one instead of zero, is because all processes are passed at least one argument; the path of the process executable file. If we run ls with no arguments, the single argument will be /usr/bin/ls, or simply ls.

If we run ls -a -l, three arguments will be passed; /usr/bin/ls, -a, and -l. We could also shorten the command by running ls -al, in which case only two arguments are passed; /usr/bin/ls and -al. The ls command has many options, so we see the number of arguments will depend on the number of options. But ls also accepts a variable number of file names, and any file names passed to ls will also increase the size of the argument list. For example, if we run ls -al file1 file2 file3, a total of five arguments will be passed.

A more interesting example is the command, ls -l file*. When we run ls, the shell is the parent process, and the shell creates the ls process by executing the fork and exec system functions. The shell also passes the environment and arguments to the new ls process it creates. Before passing arguments to a command, the shell intercepts and interprets any unquoted shell wildcard characters, such as *, to determine which file names will be passed as arguments to a command. In the example, ls -l file*, the shell will pass the argument -l, and it will search for any files in the current directory that match the pattern file*, and pass every matched file it finds as an argument to the the ls process. Consider the following example.
 
$ pwd
/tmp/lstest
$ ls -l
total 0
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file1
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file2
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file3
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file4
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file5
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:58 testfile1
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:58 testfile2
$ ls -l file*
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file1
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file2
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file3
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file4
-rw-r--r--  1 jaycs  wheel  0 Jul 26 10:57 file5
The current directory, lstest contains seven files, but only five of those files match the shell wildcard pattern, file*. Thus in this particular case, the number of arguments passed will be seven; /usr/bin/ls, -l, and the five file names file1, file2, ... file5.

What is the Size of the Argument List?

As we have learned, the argument list for Unix commands consists of the path to the executable file, the list of command options and option arguments, and with some commands, a variable size list of file names. The total size of the argument list will be the number of characters in each of these items, as well as a delimiter character for each item in the list. Using the example from above, the size of the argument list for the command, ls -al file1 file2 file3 would be:
 
/usr/bin/ls : 12
-al         :  4
file1       :  6
file2       :  6
file3       :  6
----------------
              34
The total number of bytes in this argument list is 34 bytes.  
Note:  If, for example, you use the ls command to list out files in a directory, and that directory has 10,000 files, the number of arguments to ls will be quite large and the argument count can easily exceed the maximum per process limit.   If this occurs it is better to use the find command.   There are many possibilities, the following lists all regular files in the current directory:
find ./* -print -prune
How to Set ARG/ENV Limit

On AIX 5.3 and lower, the default ARG/ENV limit is 6 4K blocks, or 24 KB. On AIX 6.1 and higher, the default is 256 4K blocks, or 1 MB. On AIX 5.3 and above, the maximum ARG/ENV size is 1024 4K blocks, or 4 MB. A block of memory equal to the current ARG/ENV setting will be allocated for every process created on the system, even if the entire block of memory is not needed for a particular process.

To change ARG/ENV with smitty, go to System Environments:Change / Show Characteristics of Operating System:ARG/ENV list size in 4K byte blocks.

To change ARG/ENV with the chdev command, run
 
# chdev -l sys0 -a ncargs=NewValue
(NewValue is the number of 4K byte blocks)

The change takes effect immediately and is preserved across a reboot.

 

[{"Line of Business":{"code":"LOB08","label":"Cognitive Systems"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SWG10","label":"AIX"},"ARM Category":[{"code":"a8m0z0000001fMuAAI","label":"AIX General Support"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Document Information

Modified date:
23 September 2020

UID

isg3T1011624