You want to look into the eval command.
eval $(awk '{print "mail -s \"welcome\"", $1}' file_a)
EDIT:
You're right @manatwork--eval as I demonstrated wouldn't really work for multiple lines. I was trying to answer Navid's question as he asked it, but really I shouldn't have been afraid to ask him why he wasn't just using a for loop, i.e.:
for m in $(<file_a); do mail -s welcome $m
Think carefully about when each command is executed, where it runs, and what input it receives.
- First the here document is expanded. This means that the
tail
/awk
pipe is executed on the local host, and the variable substitution $a
as well.
- Then the
ssh
command is executed. It receives the expanded here document; these are commands that are executed in the remote shell.
- The remote shell is executed with no arguments, so it reads commands to execute from standard input. These commands include
sudo
, but possibly (depending on the shell) some of the following lines as well.
- The remote shell executes
sudo su - someotheruser
. This runs a shell as someotheruser
which first reads and executes that user's .profile
, then reads commands from its standard input. The standard input contains whatever the first remote shell did not read, which is somewhat unpredictable (it depends on the shell and how much it happened to read from its input pipe).
- The shell running as
someotheruser
runs the commands that it read, if any.
- The shell running as
someuser
executes the if
command (if it's read it).
To avoid here document expansion, use quotes around the heredoc marker. To avoid the unholy mixture of standard inputs, use sh -c …
or be explicit as to what the second remote shell receives as its input.
ssh -t user@hostname <<'SSH_EOF'
sudo su - someotheruser <<'SU_EOF'
a=`tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SU_EOF
SSH_EOF
Do you really need to source someotheruser
's .profile
? If not, use sudo -u someotheruser
. If you do, use sudo -i -u someotheruser
. Ajust your sudoers rule accordingly.
Reading the log file is the only thing that requires elevated privileges, so it would make sense to only run the tail
command as someotheruser
.
ssh -t user@hostname <<'SSH_EOF'
a=`sudo -u someotheruser tail -10 /somepath/application.log | awk '/Agent Exited/ { print $3 }'`
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
SSH_EOF
You'll make your life a lot easier if you don't mix privilege escalation methods. Instead of using sudo
to switch from someuser
to someotheruser
, use SSH to localhost. Chaining two ssh commands is easy. Set up a key — you can even set up a key that only allows running a specific command like tail -10 /somepath/application.log
. Define an alias in your .ssh/config
to SSH through the someuser
account:
Host hostname-someotheruser
HostName hostname
UserName someotheruser
ProxyCommand ssh someuser@hostname
Then run
a=$(ssh hostname-someotheruser tail -10 /somepath/application.log |
awk '/Agent Exited/ { print $3 }')
if [ "$a" -eq 0 ]
then
echo "Success"
else
echo "Failure"
fi
Best Answer
You can use several ways:
su
. Via su you can exec the command on this way:su user -c "command"
or
the difference is when you have dash you will get the environment of target user. With this command you will be asked for the password of target user
sudo
:sudo -u user "command"
With this command you execute it with or without password (your password)
ssh
:With ssh you can exec the command with password for user, password for the key (if any)
P.S. There are also other possible methods which are rarely possible like rsh