I have seen the syntax env COLUMNS=%sin shell scripts, e.g. see the line below from the Helm package in Emacs:

env COLUMNS=%s ps -axo pid,user,pri,nice,ucomm,tty,start,vsz,%%cpu,%%mem,etime,command

What does env COLUMNS=%s do? How is it different for example from COLUMNS=%s or export COLUMNS=%s ?

Finally, does anyone know if such syntax is supported in OS X?


What does env COLUMNS=%s do?

It passes the variable COLUMNS with the value %s to the ps command and forgets, i.e. the variable does not affect the subsequent commands.

export would cause the variable to be available for subsequent commands too which may or may not be the intent.


FOO=bar command


env FOO=bar command

are identical. However, env allows an option -i that causes it to ignore the environment that it inherits.

| improve this answer | |

The following three shell snippets are equivalent (as in, they accomplish the same thing, and you have to dig in to observe any different effect):

env COLUMNS=%s ps …
COLUMNS=%s ps …
(export COLUMNS=%s; ps …)

All of them set the environment variable COLUMNS to the value %s for the invocation of the ps command. In the shell, the value of COLUMNS, if any, remains the same as before. The first snippet accomplishes this effect through the external program env, the second using pure shell syntax, the third through the export shell builtin combined with the (…) subshell construct.

This is different from

export COLUMNS=%s; ps …

which would set the environment variable COLUMNS in a way that remains in effect in the remainder of the script, and from

COLUMNS=%s; ps …

which unlike the others sets only a shell variable (which ps won't see), but does not export COLUMNS to the environment. (However, if COLUMNS was already present in the environment, it is set to %s.)

The program env may look useless, but it exists

  • because it's older than the VAR=value command shell construct;
  • because it's useful in other cases, for example when a program starts another program without going through a shell and you want to set a few environment variables;
  • because it can work systems that have a different shell (e.g. in csh, or on Windows), as long as the env command is available and in the PATH.

All the constructs mentioned here work in any Bourne/POSIX-style shell (sh, ash, bash, ksh, zsh, …), except a few antique Bourne shell versions that you're unlikely to ever encounter (and that have never been ported to Linux or OSX).

Note that COLUMNS should be a number; ps ignores it if it isn't numeric. Zsh even refuses to set COLUMNS to a non-numeric value, because it declares COLUMNS as a numeric variable by default. In the program you're quoting, %s will be replaced by a number before the string is used as a shell command.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.