How to execute .csh script with command line arguments from .csh script - shell

So I have .csh script generate.csh
I want to call another .csh script from within it.
I tried
./shell_gen.csh test1 test2.prt
But it runs shell_gen.csh but without command line arguments.
Anyone?
Thanks
generate.csh
#!/bin/csh
./shell_gen.csh test1 test2.prt
shell_gen.csh
#!/bin/csh
set source = output
############################################################
# create pbm-gifs/ directory
############################################################
set destination1 = /scratch/graphics/$1gif
echo making $destination1
if ( ! -e $destination1 ) then
mkdir $destination1
foreach file ( $source/*.pgm )
echo convert $file $destination1/$file:t:r.gif
convert $file $destination1/$file:t:r.gif
end
else
echo "$destination1/ exists"
endif

I would say you probably need to put curly braces around the positional parameter variable when they are concatenated against some other characters:
set destination1 = /scratch/graphics/${1}gif
But you might want a dot in there, too:
set destination1 = "/scratch/graphics/${1}.gif"
and quotes protect against spaces.

$1gif isn't a reference to a positional parameter.
Did you try ${1}gif as Dennis suggested? I think that should work.
ALSO I see no reference to $2 anywhere though your generate clearly sends a second argument.
Lastly the first line should probably be #!/bin/csh -f
Best,
-pbr

Related

Reading variables from config file results in "VARNAME: command not found"

What is wrong with these lines?
FASTAQ1 = "/home/mdb1c20/my_onw_NGS_pipeline/files/fastq/W2115220_S5_L001_R1_001.fastq"
FASTAQ2 = "/home/mdb1c20/my_onw_NGS_pipeline/files/fastq/W2115220_S5_L001_R2_001.fastq"
DIRECTORY = "/home/mdb1c20/my_onw_NGS_pipeline/scripts_my_first_NGS"
They are in a .conf file with other similar variables. The only difference is that these three are created with printf
printf 'FASTAQ1 = "%s"\n' "$FASTA1" >> "$DIRECTORY/$filename1/scripts/shortcut.config"
printf 'FASTAQ2 = "%s"\n' "$FASTA2" >> "$DIRECTORY/$filename1/scripts/shortcut.config"
printf 'DIRECTORY = "%s"\n' "$DIRECTORY" >> "$DIRECTORY/$filename1/scripts/shortcut.config"
When a script I am using open the .confi file its says that FASTAQ1: command not found
Apart from these three, the rest of variables were created manually in a archive .conf file but the script add these three on the go. The only thing I haven't tried because I don't know how to do that is to remove the white spaces before and after the equal simbol?
In bash, this:
var = value
is not the same as this:
var=value
The first example runs a command named "var" and passes it two arguments "=" and "value".
The second example sets a variable called "var" to "value".
It was hard to find this detail in the Bash manual, but the difference is between simple commands and assigning to variables, or shell parameters.
If you intended to source your configuration file, you should have used printf this way:
printf 'FASTAQ1=%q\n' "$FASTA1" >> "$DIRECTORY/$filename1/scripts/shortcut.config"
This allows you to store the value safely regardless if it has spaces or quotes.
The error was caused by the assignment command being interpretted as a simple command instead because of the spaces around the equal sign.
Alternatively for Bash 4.4+, you can use #Q expansion:
echo "FASTAQ1=${FASTA1#Q}" >> "$DIRECTORY/$filename1/scripts/shortcut.config"

Bash Parameter Expansion - get part of directory path

Lets say I have this variable
FILE=/data/tenant/dummy/TEST/logs/2020-02-03_16.20-LSTRM.log
I'm trying to get the name of the 4th sub directory, in this example TEST
job=${FILE%/*/*} # This gives me /data/tenant/dummy/TEST
Then
name=${job##*/}
This give me exactly what I want - Test
However when I try to use this in for loop like this:
for FILE in "/data/tenant/dummy/*/logs/*$year-*"; do
job=${FILE%/*/*}
echo $job # /data/tenant/dummy/TEST(and few other directories, so far so good)
name=${job##*/}
echo $name
done
The result of echo $name shows the list of files in my current directory I'm in instead of TEST
Main issue is the double quotes groups all files into a single long string:
for FILE in "/data/tenant/dummy/*/logs/*$year-*"
You can see this if you do something like:
for FILE in "/data/tenant/dummy/*/logs/*$year-*"
do
echo "+++++++++++++++++++"
echo "${FILE}"
done
This should print ++++++++++++++ once followed by a single line with a long list of file names.
To process the files individually remove the double quotes, eg:
for FILE in /data/tenant/dummy/*/logs/*$year-*
It's also good practice to wrap individual variable references in double quotes, eg:
job="${FILE%/*/*}"
echo "$job"
name="${job##*/}"
echo "$name"

Problem building a commandline in tcsh to be executed (by lsf), problems with vars and quotes

I am using tcsh (contract required, cannot change to bash etc), but am having a problem building up a command based on various conditions for different pieces.
Some names changed to protect the innocent...
If new or old program name, is really chosen earlier on by a preprocessor, and is hardcoded by the time this shell script gets run:
set myCMDline = newProgName
set myCMDlineTmpFile = "/tmp/myCMDlineTmpScriptFile.csh"
set bsubQname = "typical"
set bsubResources = "span[hosts=1]"
set myCMDline = "bsub -q $bsubQname -n 8 -R \"$bsubResources\" $myCMDline"
($myCMDline)
Now, I have tried several variations of the above, all not working for some reason or another. The closest I think I get is a complaint about mismatched double-quotes, even when backspacing them.
When I do an echo of $myCMDline, then that looks OK, but the execution of same must somehow be different...
set bsubResources = '"span[hosts=1]"' #double-quotes inside, single-quotes outside
set myCMDline = "bsub -q $bsubQname -n 8 -R $bsubResources $myCMDline"
.
set bsubResources = "span[hosts=1]" #double-quotes inside, single-quotes outside
set myCMDline = 'bsub -q $bsubQname -n 8 -R "$bsubResources" $myCMDline'
.
set bsubResources = "span[hosts=1]" #double-quotes inside, single-quotes outside
set myCMDline = "bsub -q $bsubQname -n 8 -R '$bsubResources' $myCMDline"
etc.
I have also tried dumping to a separate temp script file to source, but that contains the $variable names, not resolved equivalents as I would prefer, as I am doing set, not setenv, and prefer not to put these into shell vars.
First I could not echo the "#!/bin/csh -f" line, it seems to try and execute that rather than echo redirected into the temp script file, and dies.
rm -f $myCMDlineTmpFile
echo "#!/bin/csh -f > $myCMDlineTmpFile
echo "$myCMDline" >> $myCMDlineTmpFile
($myCMDlineTmpFile)
Then I tried multi-line echo, which is where I am seeing the local variable names go into the file rather than their contents:
/bin/cat > $myCMDlineTmpFile <<EOF
#!/bin/csh -f
$myCMDline
EOF
source $myCMDlineTmpFile
And then I am trying to instead use eval:
eval `echo "$myCMDline &" `
with and without the backticks etc, but complains about unknown variables for the queue name, resources etc.
Adding this echo always looks like what I want to be the commandline, between the >>> and <<<
echo "DEBUG - myCMDline= >>>$myCMDline<<<"
Please help me solve this puzzle...
set myCMDline = "bsub -q $bsubQname -n 8 -R \"$bsubResources\" $myCMDline"
($myCMDline)
This won't work because csh considers this as a single string, so it treats the whole string as one big program name. You have to define an array instead:
set myCMDline = (bsub -q $bsubQname -n 8 -R "$bsubResources" $myCMDline:gaq)
($myCMDline:gaq)
Explanation: The :gaq is a substitution quotes all strings in the list and keeps each list element intact. This is quite similar to "$#" in bash.
This is documented in History Substitution
g Apply the following modifier once to each word.
a (+) Apply the following modifier as many times as possible to a single word. `a' and `g' can be used together to apply a modifier globally. In the current implementation, using the `a' and `s' modifiers together can lead to an infinite loop. For example, `:as/f/ff/' will never terminate. This behavior might change in the future.
q Quote the substituted words, preventing further substitutions.
This is relevant due to the text in variable substitution:
The `:' modifiers described under History substitution, except for `:p', can be applied to the substitutions above. More than one may be used. (+) Braces may be needed to insulate a variable substitution from a literal colon just as with History substitution (q.v.); any modifiers must appear within the braces.

replace all variables in a $-formatted string in bash

I have some variables in a bash script. The variables comes from an other script.
I have an other variable containing a string some $names within.
How can I replace all of the variables-like names with the real values of the variables in this string? (I don't know all of the possible variables names)
Example:
#From an other place, they are imported by source <( ....)
abc="FOO"
rst="BAR"
format_base='xyz $abc $rst'
# How To Process formate_base?
????
#The Expected Result
echo "$format_base_processed"
#Should Output: xyz FOO BAR
In your example it would be sufficient to use double quotes instead of single quotes. If the variables exist at the time of reading a double quoted string, there is no problem:
abc="FOO"
rst="BAR"
format_base="xyz $abc $rst"
If (for some very complicated reason) you have to specify format_base before the used variables, you can use things like eval or bash -c:
format_base='xyz $abc $rst'
# "load" variables $abc and $rst
format_base_processed=$(eval echo "\"$format_base\"")
Note that the above command has security issues, especially if $format_base is not specified by you. Example:
format_base='$(injectedCommand)'
format_base_processed=$(eval echo "\"$format_base\"")
Here we will execute echo "$(injectedCommand)" where injectedCommand could be anything, for example rm -rf * (do not try this at home).

use bash $HOME in shell script

How to made bash to execute variable value.
For example, we have this code, where variable value was set in single quotes(!).
#!/bin/bash
V_MY_PATH='$HOME'
echo "$V_MY_PATH"
ls $V_MY_PATH
The output is
$HOME
ls: $HOME: No such file or directory
How to made bash to translate shell variable insto its value if there is some.
I want to add some code after V_MY_PATH='$HOME' to make output like echo $HOME.
It's something simple, but i'm stuck.
(NB: I know that with V_MY_PATH="$HOME", it works fine.)
EDIT PART:
I just wanted to make it simple, but I feel that some details are needed.
I'm getting parameter from a file. This part works good. I don't want to rewite it.
The problem is that when my V_MY_PATH contains a predefined variable (like $home) it's not treated like its value.
Remove the single quotes
V_MY_PATH='$HOME'
should be
V_MY_PATH=$HOME
you want to use $HOME as a variable
you can't have variables in single quotes.
Complete script:
#!/bin/bash
V_MY_PATH=$HOME
echo "$V_MY_PATH"
ls "$V_MY_PATH" #; Add double quotes here in case you get weird filenames
Output:
/home/myuser
0
05430142.pdf
4
aiSearchFramework-7_10_2007-v0.1.rar
etc.
use variable indirect reference so:
pete.mccabe#jackfrog$ p='HOME'
pete.mccabe#jackfrog$ echo $p
HOME
pete.mccabe#jackfrog$ ls ${p}
ls: cannot access HOME: No such file or directory
pete.mccabe#jackfrog$ ls ${!p}
bash libpng-1.2.44-1.el6 python-hwdata squid
...
pete.mccabe#jackfrog$
The ${!p} means take the value of $p and that value is the name of the variable who's contents I wish to reference
Use eval command:
#!/bin/bash
V_MY_PATH='$HOME'
echo "$V_MY_PATH"
eval ls $V_MY_PATH
You can use single or double quotes, and in your case, none if you prefer.
You have nothing telling bash what the variable is equal to. Maybe something like this? (unless I misunderstand what you are trying to do)
======================================================================
#!/bin/bash
#########################
# VARIABLES #
#########################
V_MY_PATH=home
#########################
# SCRIPT #
#########################
echo "What is your home path?"
read $home
echo "Your home path is $V_MY_PATH"
ls $V_MY_PATH
Of course you could also just remove the variable at the top and use:
echo "Your home path is $home"

Resources