I am trying to put below command in perl system() function.But getting so many compilation errors (syntax).
./istool export -domain serviceshost:9080 -u dsadm -p password -ar test.isx -pre -ds '-base="ENGINEHOST/Dev_Project" Jobs/Batch/\*.*'
I was using it like in perl:
system("./istool export -domain serviceshost:9080 -u dsadm -p password -ar test.isx -pre -ds '-base="ENGINEHOST/Dev_Project" Jobs/Batch/\*.*'");
can some one guide me exactly how to use it in system function?I tried escaping . also with backslash(\) in front of it.
Replace system with print, and it's obvious you didn't build the string correctly.
If you want to include a " in a string quoted with ", you need to escape it.
If you want to include a \ in a double-quoted string, you need to escape it.
Related
I am having some difficulty with a Perl script that is invoked from cron.
One of the arguments for the script is a GPG passphrase. This is later interpolated into a string that is sent to the shell.
This particular passphrase contains an open parentheses, and the script fails with a "syntax error near unexpected token `(" error.
This is the offending part of the phrase:
m3(ÃÝ4úŤ;:q!
I have tried single and double quoting it before the value is used in the script, but that does not have an effect.
The phrase works correctly when invoking GPG directly from the shell, just not when it gets interpolated into the following:
`gpg --passphrase $gpgpp --batch -o $gpgofile -d $file`;
Where $gpgpp is the passphrase variable.
What is the correct way to escape this, and other potentially problematic characters?
The \Q and \E escape sequences are used to escape all "special" characters between them.
`gpg --passphrase \Q$gpgpp\E --batch -o $gpgofile -d $file`;
This should be done any time you have a variable that may contain characters which need to be escaped.
http://perldoc.perl.org/functions/quotemeta.html
Enclose the variables in quotes:
gpg --passphrase "$gpgpp" --batch -o "$gpgofile" -d "$file"
Otherwise, the shell will try to interpret contents of the variables as expressions.
I am a beginner with Perl. I am using the Below Perl Command To Search and Replace "/$" Sequence in my tcl Script. This works well When used on the linux Command Line directly.
perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl
I am calling to Call the above Perl One liner in another Perl script using System Command and only with " ` " Back Tick.
system(`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl`);
`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl`;
I am getting the Below error. Please Help With this issue.
Bareword found where operator expected at -e line 1, near "$/g"
(Missing operator before g?)
Final $ should be \$ or $name at -e line 1, within string
syntax error at -e line 1, near "s//$/"
Execution of -e aborted due to compilation errors.
I Dont Know if I Can use any other Separation Operator like % and # just like SED command but, When I used '%' operator for separation, I didn't see error but job is not done.
`perl -p -i -e 's%\/\$%\/\\\$%g' sed_list.tcl`;
I couldn't find sufficient results for this particular issue of '$' variable on the web. Any help is appreciated.
Some one here Suggested that I should Escape all Back Slashes while using System Command or calling another command using BackTicks from inside a perl script. But later they have deleted their answer. It worked for me. I would like to thank every one for taking effort and helping me out in solving my question.
Here is the correct working code.
`perl -p -i -e 's/\\\/\\\$/\\\/\\\\\\\$/g' sed_list_gen.tcl`;
or Use System function as shown Below
system("perl -p -i -e 's/\\\/\\\$/\\\/\\\\\\\$/g' sed_list_gen.tcl");
Thanks once again for the community for helping me out. . .
You can execute an external command by passing the command to a system function or by using backticks(``) operator. Please pass the command to the system() function as a string:
system(q{perl -p -i -e 's/\/\$/\/\\\$/g' sed_list.tcl})
or use backticks as:
`perl -p -i -e 's/\/\$/\/\\\$/g' sed_list_gen.tcl`
Edit:
As suggested by Paul in the comments.
I am trying to interface between tk and cshell-script.
I am able to collect data using tk:
label .firstColumn.s.variable.label -text "myFirstVariable" -background $color3
entry .firstColumn.s.variable.entry -textvariable program
But when I try to run the command it does not work
button .secondColumn.o.buttons.go -text "Run Now" \
-command "exec sed -i {s/ABC/$myFirstVariable/g} runme.sh \
>! runmeNow.sh ; ./runmeNow"
It changes ABC to blank in runmeNow.sh file.
Is there any better way to achieve it?
I want to replace a place-holder predefined in cshell-script (runme.sh). My place holder is ABC. Then I want to pipe it to a different file, then run this file. runme.sh has UNIX based run file.
Seems to me that tk is interpreting $myFirstVariable as a variable of its own, while you'd like it to be forwarded to shell. Escaping the dollar sign with a backslash may not be enough: exec is a Tcl command and doesn't use a shell, so we may have to call one to expand shell variable:
button .secondColumn.o.buttons.go -text "Run Now" \
-command "exec /bin/sh -i {sed "s/ABC/$myFirstVariable/g" runme.sh \
> runmeNow.sh ; ./runmeNow.sh}"
I am using this command fine:
ssh user#ip 'bash -s' -- < /usr/local/nagios/libexec/check_ssh_mem.sh
I don't like the results of that script so want to use a perl script instead and use this:
ssh user#ip 'perl -s' -- < /usr/local/nagios/libexec/check_mem.pl
check_mem.pl v1.0 - Nagios Plugin
usage:
check_mem.pl -<f|u> -w <warnlevel> -c <critlevel>
options:
-f Check FREE memory
-u Check USED memory
-C Count OS caches as FREE memory
-w PERCENT Percent free/used when to warn
-c PERCENT Percent free/used when critical
As you can see, I get proper feedback from the script. I want to pass it the -f, -w and -c variables but get errors when trying to do that.
man perlrun says:
Upon startup, Perl looks for your program in one of the following places
...
3. Passed in implicitly via standard input. This works only if there are
no filename arguments--to pass arguments to a STDIN-read program you must
explicitly specify a "-" for the program name.
So, you can use this:
ssh user#ip 'perl - -f -u -C' -- < /usr/local/nagios/libexec/check_mem.pl
The arguments after the - are passed to the script you are running.
You don't need the -s argument - I assume you copied that from your original bash implementation, but -s has a different meaning for perl.
I have a file named check.txt which has the below contents:
$ cat check.txt
~/bin/tibemsadmin -server $URL-user $USER -password $PASWRD
$
I have a main script where the values of $URL, $USER, $PASWRD are obtained from the main script. I want to use the SED utility to replace the $URL, $USER, $PASWRD to the actual values in the check.txt.
I am trying like this but it fails.
emsurl=tcp://myserver:3243
emsuser=test
emspasswd=new
sed s/$URL/${emsurl}/g check.txt >> check_new.txt
sed s/$USER/${emsuser}/g check.txt_new.txt >> check_new_1.txt
sed s/PASWRD/${emspasswd}/g check_new_1.txt >> final.txt
My final.txt output is desired as below:
~/bin/tibemsadmin -server tcp://myserver:3243 -user test -password new
Could you please help me?
You have to be rather careful with your use of quotes. You also need to learn how to do multiple operations in a single pass, and/or how to use pipes.
emsurl=tcp://myserver:3243
emsuser=test
emspasswd=new
sed -e "s%\$URL%${emsurl}%g" \
-e "s%\$USER%${emsuser}%g" \
-e "s%\$PASWRD%${emspasswd}%g" check.txt >final.txt
Your problem is that the shell expanded the '$URL' in your command line (probably to nothing), meaning that sed got to see something other than what you intended. By escaping the $ with the \, sed gets to see what you intended.
Note that I initially used / as the separator in the substitute operations; however, as DarkDust rightly points out, that won't work since there are slashes in the URLs. My normal fallback character is % - as now shown - but that can appear in some URLs and might not be appropriate. I'd probably use a control character, such as control-A, if I needed to worry about that - or I'd use Perl which would be able to play without getting confused.
You can also combine the three separate -e expressions into one with semi-colons replacing them. However, I prefer the clarity of the three operations clearly separated.
You could take a slightly different approach by modifying your main script as follows :-
export URL="tcp://myserver:3243"
export USER=test
export PASWRD=new
. ./check.txt
This sets up the variables and then runs check.txt within the context of your main script
Although you don't say what's failing I guess I see the problems.
I suggest you do this:
sed "s|\$URL|${emsurl}|g"
That is, the first $ needs to be escaped because you want it literally. Then, instead of / I suggest you use | (pipe) as delimiter since it's not used in your strings. Finally, use " to ensure the content is interpreted as string by the shell.
You can then pipe everything together to not need any temporary files:
sed "s|\$URL|${emsurl}|g" | sed "s|\$USER|${emsuser}|g" | sed "s|\$PASSWRD|${emspasswd}|g"
Variable substitution should be outside sed expression and '$' should be escaped; in your case something like this:
sed -e 's/\$URL/'$emsurl'/g' -e 's/\$USER/'$emsuser'/g' -e 's/\$PASSWORD/'$emaspasswd'/g'
Anyway in your place I would avoid using $ to match placeholders in a template file, because it's causing confusion with BASH variables, use a different pattern instead (for instance #URL#).