Reputation: 23
i am trying to run the below set of commands using sh -c
sh -c "
Dup_flag=`wc -l test.dat | awk '{print $1}'`;
user='[email protected]';
text='Hi';
subject='Notification';
if [ $Dup_flag -eq 0 ];
then
echo $Dup_flag | mailx -r $user -s $subject $user;
fi
"
it is not giving the desired result
when i run the same in a script
Dup_flag=`wc -l test.dat | awk '{print $1}'`
user='[email protected]'
text='Hi'
subject='Notification'
if [ $Dup_flag -eq 8 ]
then
echo $Dup_flag | mailx -r $user -s $subject $user
fi
it is giving the desired result
can some one help me where i am doing wrong here .i haven to run them with only sh -c
Thanks
Upvotes: 1
Views: 786
Reputation: 754570
The first version fails because the double-quoted argument is processed by the shell that invokes sh -c "…your script…"
.
That means that the wc
and awk
are run before the sh -c
is invoked. Also, the various variable references $Dup_flag
etc are evaluated by the invoking shell, not by the invoked shell.
You'd need to use backslashes to escape the back-ticks and dollar signs. Even if you changed to the $(…)
notation, you'd still have to escape that $
.
Or use single quotes around the sh -c '…your script…'
and use double quotes where appropiate inside the script.
I thought I'd added the 'Escapes' and 'Single quotes' sections before. The submission process to SO glitched (paused); probably my internet connection at fault, but I seem to have closed the tab without noticing it was not successful.
sh -c "
Dup_flag=\`wc -l test.dat | awk '{print \$1}'\`;
user='[email protected]';
subject='Notification'
if [ \$Dup_flag -eq 0 ]
then
echo \$Dup_flag | mailx -r \$user -s \$subject \$user
fi
"
sh -c '
Dup_flag=`wc -l test.dat | awk "{print $1}"`
user="[email protected]"
subject="Notification"
if [ "$Dup_flag" -eq 0 ]
then
echo "$Dup_flag" | mailx -r "$user" -s "$subject" "$user"
fi
'
Note that the single-quoted version will make it much easier to have multi-word subject lines for the email, etc.
In both versions, I deleted text
as it is unused. The semicolons aren't necessary when the command is spread over multiple lines (so I removed them). They'd be necessary if it was all flattened onto a single line.
Actually, I need to run the mentioned commands in an Informatica command task which runs the commands as
sh -c " my script "
.
Ouch. That adds a number of levels of possible confusion. It could be that the Informatica code creates a shell command like this:
char *args[] = { "sh", "-c", your_string, 0 };
execvp(args[0], args);
In that case, my diagnosis of your problem is off the mark; nothing except the final shell interprets the contents of your string.
OTOH, they could use:
char buffer[4096];
snprintf(buffer, sizeof(buffer), "sh -c \"%s\"", your_string);
system(buffer);
In that case, the system()
function runs a shell that in turn analyzes and runs the shell that actually runs your script. My analysis then comes into effect.
There are likely other ways to achieve the job; they might have subtly different effects.
Upvotes: 2
Reputation: 23
it worked after escaping the $ and back-ticks
sh -c "
Dup_flag=\`wc -l test.dat | awk '{print \$1}'\`
user='[email protected]';
text='Hi';
subject='Notification';
if [ \$Dup_flag -eq 8 ]
then
echo \$Dup_flag | mailx -r \$user -s \$subject \$user;
fi
"
Thanks Jonathan
Upvotes: 1