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}"
Related
I want to write a PowerShell script that includes a single command that is split over new lines, such as (the actual command I am trying to run is longer):
ssh \
-L 8080:localhost:8080 \
foo#bar.com
However the \ doesn't escape the new line (neither does /).
Use the backtick ( ` ), like this:
Write-Output `
"Hello world!"
I would like to pass LSB_JOBINDEX to as an argument to my script instead of using an environment variable.
This makes my script more LSF agnostic and avoids creating a helper script that uses the environment variable.
However, I was not able to use LSB_JOBINDEX in arguments: it only works as part of the initial command string.
For example, from a bash shell, I use the test command:
bsub -J 'myjobname[1-4]' -o bsub%I.log \
'echo $LSB_JOBINDEX' \
'$LSB_JOBINDEX' \
\$LSB_JOBINDEX \
'$LSB_JOBINDEX' \
"\$LSB_JOBINDEX"
and the output of say bsub2.log is:
2 $LSB_JOBINDEX $LSB_JOBINDEX $LSB_JOBINDEX $LSB_JOBINDEX
So in this case, only the first $LSB_JOBINDEX got expanded, but not any of the following ones.
But I would rather not pass the entire command as a single huge string as the 'echo $LSB_JOBINDEX' in this example. I would prefer to just use separate arguments as in a regular bash command.
I've also tried to play around with %I but it only works for -o and related bsub options, not for the command itself.
Related: Referencing job index in LSF job array
Tested in LSF 10.1.0. Related documentation: https://www.ibm.com/support/knowledgecenter/en/SSWRJV_10.1.0/lsf_admin/job_array_cl_args.html
bsub will add single quotes around the arguments if the argument starts with $. For example. If the bsub command line is
bsub command -a $ARG1 -b $ARG2
Then bsub will add quotes to the arguments to the 2nd and 4th parameters. The command is stored like this
command -a '$ARG1' -b '$ARG2'
One way to prevent this is to put the commands in a script. Like this:
$ cat cmd
echo $LSB_JOBINDEX
echo "line 2"
echo $LSB_JOBINDEX
Then run your job like this:
$ bsub -I < cmd
Job <2669> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0
line 2
0
Note that the -I is not needed. Its just so you can see the job output on the bsub's stdout.
EDIT
OK. Looks like this works. But its not really a serious answer since it's so ugly. The thing is that bsub will surround the argument with single quotes if the argument starts with $. So the strategy is to find some way to make sure that the first character in the argument isn't a $. One way is to put any character other than $ as the first character of the argument. Follow it by a backspace literal, followed by the $. Note that it needs to be the actual backspace character, not ^ followed by H. Use ctrl-v followed by a ctrl-h to get the literal appended to the command line.
$ bsub -I echo "x^H\$LSB_JOBINDEX" "x^H\$LSB_JOBINDEX"
Job <2686> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0 0
EDIT2
A tab literal also works. Not that its much better.
$ bsub -I echo " \$LSB_JOBINDEX" " \$LSB_JOBINDEX"
Job <2687> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0 0
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.
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'm trying to run a perl script from within a bash script (I'll change this design later on, but for now, bear with me). The bash script receives the argument that it will run. The argument to the script is as follows:
test.sh "myscript.pl -g \"Some Example\" -n 1 -p 45"
within the bash script, I simple run the argument that was passed:
#!/bin/sh
$1
However, in my perl script the -g argument only gets "Some (that's with the quotes), instead of the Some Example. Even if I quote it, it cuts off because of the whitespace.
I tried escaping the whitespace, but it doesn't work... any ideas?
To run it as posted test.sh "myscript.pl -g \"Some Example\" -n 1 -p 45" do this:
#!/bin/bash
eval "$1"
This causes the $1 argument to be parsed by the shell so the individual words will be broken up and the quotes removed.
Or if you want you could remove the quotes and run test.sh myscript.pl -g "Some Example" -n 1 -p 45 if you changed your script to:
#!/bin/bash
"$#"
The "$#" gets replaced by all the arguments $1, $2, etc., as many as were passed in on the command line.
Quoting is normally handled by the parser, which isn't seeing them when you substitute the value of $1 in your script.
You may have more luck with:
#!/bin/sh
eval "$1"
which gives:
$ sh test.sh 'perl -le "for (#ARGV) { print; }" "hello world" bye'
hello world
bye
Note that simply forcing the shell to interpret the quoting with "$1" won't work because then it tries to treat the first argument (i.e., the entire command) as the name of the command to be executed. You need the pass through eval to get proper quoting and then re-parsing of the command.
This approach is (obviously?) dangerous and fraught with security risks.
I would suggest you name the perl script in a separate word, then you can quote the parameters when referring to them, and still easily extract the script name without needing the shell to split the words, which is the fundamental problem you have.
test.sh myscript.pl "-g \"Some Example\" -n 1 -p 45"
and then
#!/bin/sh
$1 "$2"
if you really have to do this (for whatever reason) why not just do:
sh test.sh "'Some Example' -n 1 -p 45"
in:
test.sh
RUN=myscript.pl
echo `$RUN $1
(there should be backticks ` before $RUN and after $1)