1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
|
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" This code is derived from software contributed to Berkeley by
.\" the Institute of Electrical and Electronics Engineers, Inc.
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" From @(#)printenv.1 8.1 (Berkeley) 6/6/93
.\" From FreeBSD: src/usr.bin/printenv/printenv.1,v 1.17 2002/11/26 17:33:35 ru Exp
.\" $FreeBSD$
.\"
.Dd June 20, 2005
.Dt ENV 1
.Os
.Sh NAME
.Nm env
.Nd set and print environment
.Sh SYNOPSIS
.Nm
.Op Fl iv
.Op Fl P Ar altpath
.Op Fl S Ar string
.Op Ar name Ns = Ns Ar value ...
.Op Ar utility Op Ar argument ...
.Sh DESCRIPTION
The
.Nm
utility executes another
.Ar utility
after modifying the environment as
specified on the command line.
Each
.Ar name Ns = Ns Ar value
option specifies the setting of an environment variable,
.Ar name ,
with a value of
.Ar value .
All such environment variables are set before the
.Ar utility
is executed.
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl i
Execute the
.Ar utility
with only those environment variables specified by
.Ar name Ns = Ns Ar value
options.
The environment inherited
by
.Nm
is ignored completely.
.\" -P
.It Fl P Ar altpath
Search the set of directories as specified by
.Ar altpath
to locate the specified
.Ar utility
program, instead of using the value of the PATH environment variable.
.\" -S
.It Fl S Ar string
Split apart the given
.Ar string
into multiple strings, and process each of the resulting strings
as separate arguments to the
.Nm
utility.
The
.Fl S
option recognizes some special character escape sequences and
also supports environment-variable substitution, as described
below.
.\" -v
.It Fl v
Print verbose information for each step of processing done by the
.Nm
utility.
Additional information will be printed if
.Fl v
is specified multiple times.
.El
.Pp
The above options are only recognized when they are specified
before any
.Ar name Ns = Ns Ar value
options.
.Pp
If no
.Ar utility
is specified,
.Nm
prints out the names and values
of the variables in the environment, with one name/value pair per line.
.\"
.Ss Details of -S (split-string) processing
.Pp
The processing of the
.Fl S
option will split the given
.Ar string
into separate arguments based on any space or <tab> characters found in the
.Ar string .
Each of those new arguments will then be treated as if it had been
specified as a separate argument on the original
.Nm
command.
.Pp
Spaces and tabs may be embedded in one of those new arguments by using
single (``\ '\ '') or double (``"'') quotes, or backslashes (``\e'').
Single quotes will escape all non-single quote characters, up to
the matching single quote.
Double quotes will escape all non-double quote characters, up to
the matching double quote.
It is an error if the end of the
.Ar string
is reached before the matching quote character.
.Pp
If
.Fl S
would create a new argument that starts with the
.Ql #
character, then that argument and the remainder of the
.Ar string
will be ignored.
The
.Ql \e#
sequence can be used when you want a new argument to start
with a
.Ql #
character, without causing the remainder of the
.Ar string
to be skipped.
.Pp
While processing the
.Ar string
value,
.Fl S
processing will treat certain character combinations as escape
sequences which represent some action to take.
The character escape sequences are in backslash notation.
The characters and their meanings are as follows:
.Pp
.Bl -tag -width Ds -offset indent -compact
.It Cm \ec
Ignore the remaining characters in the
.Ar string .
This must not appear inside a double-quoted string.
.It Cm \ef
Replace with a <form-feed> character.
.It Cm \en
Replace with a <new-line> character.
.It Cm \er
Replace with a <carriage return> character.
.It Cm \et
Replace with a <tab> character.
.It Cm \ev
Replace with a <vertical tab> character.
.It Cm \e#
Replace with a
.Ql #
character.
This would be useful when you need a
.Ql #
as the first character in one of the arguments created
by splitting apart the given
.Ar string .
.It Cm \e$
Replace with a
.Ql $
character.
.It Cm \e_
If this is found inside of a double-quoted string, then replace it
with a single blank.
If this is found outside of a quoted string, then treat this as the
separator character between new arguments in the original
.Ar string .
.It Cm \e"
Replace with a <double quote> character.
.It Cm \e\'
Replace with a <single quote> character.
.It Cm \e\e
Replace with a backslash character.
.El
.Pp
The sequences for <single-quote> and backslash are the only sequences
which are recognized inside of a single-quoted string.
The other sequences have no special meaning inside a single-quoted
string.
All escape sequences are recognized inside of a double-quoted string.
It is an error if a single
.Ql \e
character is followed by a character other than the ones listed above.
.Pp
The processing of
.Fl S
also supports substitution of values from environment variables.
To do this, the name of the environment variable must be inside of
.Ql ${} ,
such as: ${SOMEVAR}.
The common shell syntax of $SOMEVAR is not supported.
All values substituted will be the values of the environment variables
as they were when the
.Nm
utility was originally invoked.
Those values will not be checked for any of the escape sequences as
described above.
And any settings of
.Ar name Ns = Ns Ar value
will not effect the values used for substitution in
.Fl S
processing.
.Pp
Also,
.Fl S
processing can not reference the value of the special parameters
which are defined by most shells.
For instance,
.Fl S
can not recognize special parameters such as:
.Ql $* ,
.Ql $@ ,
.Ql $# ,
.Ql $?
or
.Ql $$
if they appear inside the given
.Ar string .
.\"
.Ss Use in shell-scripts
The
.Nm
utility is often used as the
.Ar interpreter
on the first line of interpreted scripts, as
described in
.Xr execve 2 .
.Pp
Note that the way the kernel parses the
.Ql #!
(first line) of an interpreted script has changed as of
.Fx 6.0 .
Prior to that, the
.Fx
kernel would split that first line into separate arguments based
on any whitespace (space or <tab> characters) found in the line.
So, if a script named
.Pa /usr/local/bin/someport
had a first line of:
.Pp
.D1 Li "#!/usr/local/bin/php -n -q -dsafe_mode=0"
.Pp
then the
.Pa /usr/local/bin/php
program would have been started with the arguments of:
.Pp
.D1 Li "arg[0] = '/usr/local/bin/php'"
.D1 Li "arg[1] = '-n'"
.D1 Li "arg[2] = '-q'"
.D1 Li "arg[3] = '-dsafe_mode=0'"
.D1 Li "arg[4] = '/usr/local/bin/someport'"
.Pp
plus any arguments the user specifed when executing
.Pa someport .
However, this processing of multiple options on the
.Ql #!
line is not the way any other operating system parses the
first line of an interpreted script.
So after a change which was made for
.Fx 6.0
release, that script will result in
.Pa /usr/local/bin/php
being started with the arguments of:
.Pp
.D1 Li "arg[0] = '/usr/local/bin/php'"
.D1 Li "arg[1] = '-n -q -dsafe_mode=0'"
.D1 Li "arg[2] = '/usr/local/bin/someport'"
.Pp
plus any arguments the user specifed.
This caused a significant change in the behavior of a few scripts.
In the case of above script, to have it behave the same way under
.Fx 6.0
as it did under earlier releases, the first line should be
changed to:
.Pp
.D1 Li "#!/usr/bin/env -S /usr/local/bin/php -n -q -dsafe_mode=0"
.Pp
The
.Nm
utility will be started with the entire line as a single
argument:
.Pp
.D1 Li "arg[1] = '-S /usr/local/bin/php -n -q -dsafe_mode=0'"
.Pp
and then
.Fl S
processing will split that line into separate arguments before
executing
.Pa /usr/local/bin/php .
.\"
.Sh ENVIRONMENT
The
.Nm
utility uses the
.Ev PATH
environment variable to locate the requested
.Ar utility
if the name contains no
.Ql /
characters, unless the
.Fl P
option has been specifed.
.Sh EXIT STATUS
.Ex -std
An exit status of 126 indicates that
.Ar utility
was found, but could not be executed.
An exit status of 127 indicates that
.Ar utility
could not be found.
.Sh EXAMPLES
Since the
.Nm
utility is often used as part of the first line of an interpreted script,
the following examples show a number of ways that the
.Nm
utility can be useful in scripts.
.Pp
The kernel processing of an interpreted script does not allow a script
to directly reference some other script as its own interpreter.
As a way around this, the main difference between
.Pp
.D1 Li #!/usr/local/bin/foo
and
.D1 Li "#!/usr/bin/env /usr/local/bin/foo"
.Pp
is that the latter works even if
.Pa /usr/local/bin/foo
is itself an interpreted script.
.Pp
Probably the most common use of
.Nm
is to find the correct interpreter for a script, when the interpreter
may be in different directories on different systems.
The following example will find the
.Ql perl
interpreter by searching through the directories specifed by PATH.
.Pp
.D1 Li "#!/usr/bin/env perl"
.Pp
One limitation of that example is that it assumes the user's value
for PATH is set to a value which will find the interpreter you want
to execute.
The
.Fl P
option can be used to make sure a specific list of directories are
used in the search for
.Ar utility .
Note that the
.Fl S
option is also required for this example to work correctly.
.Pp
.D1 Li "#!/usr/bin/env -S -P/usr/local/bin:/usr/bin perl"
.Pp
The above finds
.Ql perl
only if it is in
.Pa /usr/local/bin
or
.Pa /usr/bin .
That could be combined with the present value of PATH, to provide
more flexibility.
Note that spaces are not required between the
.Fl S
and
.Fl P
options:
.Pp
.D1 Li "#!/usr/bin/env -S-P/usr/local/bin:/usr/bin:${PATH} perl"
.Sh COMPATIBILITY
The
.Nm
utility accepts the
.Fl
option as a synonym for
.Fl i .
.Sh SEE ALSO
.Xr printenv 1 ,
.Xr sh 1 ,
.Xr execvp 3 ,
.Xr environ 7
.Sh STANDARDS
The
.Nm
utility conforms to
.St -p1003.1-2001 .
The
.Fl P , S
and
.Fl v
options are non-standard
.Fx
extensions which may not be available on other operating systems.
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.4 .
The
.Fl P , S
and
.Fl v
options were added in
.Fx 6.0 .
.Sh BUGS
The
.Nm
utility does not handle values of
.Ar utility
which have an equals sign
.Pq Ql =
in their name, for obvious reasons.
.Pp
The
.Nm
utility does not take multibyte characters into account when
processing the
.Fl S
option, which may lead to incorrect results in some locales.
|