Reputation: 10093
In a given shell, normally I'd set a variable or variables and then run a command. Recently I learned about the concept of prepending a variable definition to a command:
FOO=bar somecommand someargs
This works... kind of. It doesn't work when you're changing a LC_*
variable (which seems to affect the command, but not its arguments, for example, [a-z]
char ranges) or when piping output to another command thusly:
FOO=bar somecommand someargs | somecommand2 # somecommand2 is unaware of FOO
I can prepend somecommand2 with FOO=bar
as well, which works, but which adds unwanted duplication, and it doesn't help with arguments that are interpreted depending on the variable (for example, [a-z]
).
So, what's a good way to do this on a single line?
I'm thinking something on the order of:
FOO=bar (somecommand someargs | somecommand2) # Doesn't actually work
I got lots of good answers! The goal is to keep this a one-liner, preferably without using export
. The method using a call to Bash was best overall, though the parenthetical version with export
in it was a little more compact. The method of using redirection rather than a pipe is interesting as well.
Upvotes: 598
Views: 518736
Reputation: 442
some_var="some_value" && echo "${some_var}"
Also works. It is similar to:
some_var="some_value"; echo "${some_var}"
Upvotes: 2
Reputation: 4890
Use env
.
For example, env FOO=BAR command
. Note that the environment variables will be restored/unchanged again when command
finishes executing.
Just be careful about shell substitution happening, i.e. if you want to reference $FOO
explicitly on the same command line, you may need to escape it so that your shell interpreter doesn't perform the substitution before it runs env
.
$ export FOO=BAR
$ env FOO=FUBAR bash -c 'echo $FOO'
FUBAR
$ echo $FOO
BAR
Upvotes: 91
Reputation: 21269
How about exporting the variable, but only inside the subshell?:
(export FOO=bar && somecommand someargs | somecommand2)
Keith has a point, to unconditionally execute the commands, do this:
(export FOO=bar; somecommand someargs | somecommand2)
Upvotes: 342
Reputation: 1040
A simple approach is to make use of
;
For example:
ENV=prod; ansible-playbook -i inventories/$ENV --extra-vars "env=$ENV" deauthorize_users.yml --check
command1; command2
executes command2 after executing command1, sequentially. It does not matter whether the commands were successful or not.
Upvotes: 30
Reputation: 14900
Use a shell script:
#!/bin/bash
# myscript
FOO=bar
somecommand someargs | somecommand2
> ./myscript
Upvotes: -8
Reputation: 46823
You can also use eval
:
FOO=bar eval 'somecommand someargs | somecommand2'
Since this answer with eval
doesn't seem to please everyone, let me clarify something: when used as written, with the single quotes, it is perfectly safe. It is good as it will not launch an external process (like the accepted answer) nor will it execute the commands in an extra subshell (like the other answer).
As we get a few regular views, it's probably good to give an alternative to eval
that will please everyone, and has all the benefits (and perhaps even more!) of this quick eval
“trick”. Just use a function! Define a function with all your commands:
mypipe() {
somecommand someargs | somecommand2
}
and execute it with your environment variables like this:
FOO=bar mypipe
Upvotes: 64
Reputation: 360075
FOO=bar bash -c 'somecommand someargs | somecommand2'
Upvotes: 505