This question already has an answer here:
Echo '$(VAR)' to a file
(1 answer)
Closed 6 years ago.
I am using a Makefile for my projects. I need my makefile to echo the date and my computer name to a file:
files:
echo " * Author: $(whoami)" >> myFile
echo " * Created on: $(date +%D)" >> myFile
I would assume an file looking like this:
* Author: eDeviser
* Created on: 02.01.2017
Nevertheless it looks like this:
* Author:
* Created on:
I tried to type the two lines directly into my terminal. This works very well:
$echo " * Author: $(whoami)" >> myFile
$echo " * Created on: $(date +%D)" >> myFile
$cat myfile
* Created on: 01/02/17
* Author: lukas
Where is my mistake?
make also uses the $( ) syntax for its variables and functions.
Use $$ to get a single $ into the command you want to run:
files:
echo " * Author: $$(whoami)" >> myFile
echo " * Created on: $$(date +%D)" >> myFile
Related
Can anyone help me to modify my script. Because it does not work. Here are three scripts.
1) pb.sh, use delphicpp_release software to read the 1brs.ab.sh and will give the output as 1brs.ab.out
2) 1brs.ab.sh, use for input parameter where a.sh(another script for protein structure), chramm.siz, charmm.crg are file for atom size and charge etc. rest of the parameters for run the delphicpp_release software.
3) a.sh, use for read several protein structures, which will be in the same directory.
my script_1 = pb.sh:
./delphicpp_release 1brs.ab.sh >1brs.ab.out
echo PB-Energy-AB = $(grep -oP '(?<=Energy> Corrected:).*' 1brs.ab.out) >>PB-energy.dat
cat PB-energy.dat
script_2 = 1brs.ab.sh:
in(pdb,file="a.sh")
in(siz,file="charmm.siz")
in(crg,file="charmm.crg")
perfil=70
scale=2.0
indi=4
exdi=80.0
prbrad=1.4
salt=0.15
bndcon=2
maxc=0.0001
linit=800
energy(s)
script_3 = a.sh:
for i in $(seq 90000 20 90040); do
$i.pdb
done
As we don't know what software is, something like
for ((i=90000;i<=100000;i+=20)); do
./software << " DATA_END" > 1brs.$i.a.out
scale=2.0
in(pdb,file="../$i.ab.pdb")
in(siz,file="charmm.siz")
in(crg,file="charmm.crg")
indi=z
exdi=x
prbrad=y
DATA_END
echo Energy-A = $(grep -oP '(?<=Energy>:).*' 1brs.$i.a.out) >>PB-energy.dat
done
A more POSIX shell compliant version
i=90000
while ((i<=100000)); do
...
((i+=20));
done
EDIT: Without heredoc
{
echo 'scale=2.0'
echo 'in(pdb,file="../'"$i"'.ab.pdb")'
echo 'in(siz,file="charmm.siz")'
echo 'in(crg,file="charmm.crg")'
echo 'indi=z'
echo 'exdi=x'
echo 'prbrad=y'
} > $i.ab.sh
./software <$i.ab.sh >$i.ab.out
but as question was changed I'm not sure to understand it.
I have a crontable that executes a script with different args
0,5,10 * * * * /path/to/logScript "script2"
0,5,10 * * * * /path/to/logScript "script1"
0,5,10 * * * * /path/to/logScript "script3"
script
#!/bin/bash
script=$1
$script args >/path/tmp/log.out 2>/path/tmp/log.err
if [ ! -s /path/tmp/log.err ]; then
echo -n "$(date) success: " >> /path/logfile
cat /path/tmp/log.out >> /path/logfile
else
echo -n "$(date) errors: " >> /path/logfile
cat /path/tmp/log.err >> /path/logfile
fi
The issue that I think i'm having is with the execution of the script in the same time. The script doen't get the right value of return (to know wheter it's stderr or stdout). If i execute the crontable lines one after one in a terminal it works fine but when it's executed automatically the data i get is incorrect.
I tried to solve this by making this changement to crontable but i still have the same issue.
0,5,10 * * * * /path/to/logScript "script2"&
0,5,10 * * * * /path/to/logScript "script1"&
0,5,10 * * * * /path/to/logScript "script3"&
if all commands are running at same time, think you could combine the command in a unique one, using & at end of commands to push them to background mode, like this:
0,5,10 * * * * /bin/bash -c '/path/to/logScript "script2" & /path/to/logScript "script1" & /path/to/logScript "script3" & '
you need to run it as a background process (add "&" at the end of the process line so you can "spawn" them)
you can also wrap it into a loop with i being number of processes and run it within the same file.
func () {
#do this
#do that
#hit him with a bat
}
then in sh
#!/bin/bash
for i in $(seq 0 5);
do
function() &
echo "child pid: " $!
done
I am trying to echo / redirect to file two or three variables and asterisk;
However, as long as I am trying to include more than only one then my variables disappears.
Loading variables from file.
var:
CMD=/home/user1/command.sh
HOUR=17
MN=00
Here is a snippet of my script:
#!/bin/bash
. var
if [ "${MN}" == "00" ];
then
MN=0
fi
echo "${MN} ${HOUR} * * * user1 ${CMD}" >> ./test.log
the output look like the following which does not include all variables:
* * * root /home/user1/command.sh
It seems that for some reason while loading these variables from file; these cannot be reused.
As soon as I set them manually as part of the script itself, the output is as below and correct:
0 17 * * * root /home/user1/command.sh
Any help would be appreciated,
Many thanks,
AL.
Crontab execute that script not in /home/user1/ folder.
So you need use /home/user1/var for variable include or do
cd /home/user1/
before include file with variables.
I have a script I am working on that reads off of a text file and will use the information stored in the text file to put each line entered in as an array. This array is a reference to files that are imported to a directory in another script. The problem is i built a function to zip the contents of the directory and change it's ownerships, but when I run the script it was zipping and attempting to change ownerships of the pwd. Here is my code below:
file=~/exporttool/zipFiles.txt
index=0
declare -a studyinstanceuids
while read line ; do
studyinstanceuids[$index]="$line"
index=$((index+1))
echo $line
done < $file
for i in "${studyinstanceuids[#]}"
do
echo "$i" | ./cmd2;
done
echo "Exams are in!";
##Function with argument that will take prompt to change ownerships
echo "What is the name of the owner: "
read $owner
zipForOwner(){
arg1=$1
for i in "${studyinstanceuids[#]}"; do
zip -r ~/export/"${studyinstanceuids[#]}"/20140620_"${studyinstanceuids[#]}".zip .
sudo chown $1:$1 ~/export/"${studyinstanceuids[#]}"/"${studyinstanceuids[#]}".zip
sudo mv ~/export/"${studyinstanceuids[#]}"/"${studyinstanceuids[#]}".zip ~/home/"$1"
done
}
zipForOwner $owner
exit;
Does anyone have any suggestions
EDIT: Heere are my results running in xterm
+ file=/home/support/exporttool/zipFiles.txt
+ index=0
+ declare -a studyinstanceuids
+ read line
+ studyinstanceuids[$index]=1.3.46.670589.16.11.8.34254330145.20140603.134057.0
+ index=1
+ echo 1.3.46.670589.16.11.8.34254330145.20140603.134057.0
1.3.46.670589.16.11.8.34254330145.20140603.134057.0
+ read line
+ for i in '"${studyinstanceuids[#]}"'
+ echo 1.3.46.670589.16.11.8.34254330145.20140603.134057.0
+ ./cmd2
Please enter StudyInstanceUID:
+ echo 'Exams are in!'
Exams are in!
+ echo 'What is the name of the owner: '
What is the name of the owner:
+ read
sftpuser
+ zipForOwner
+ arg1=
+ for i in '"${studyinstanceuids[#]}"'
+ zip -r /home/support/export/1.3.46.670589.16.11.8.34254330145.20140603.134057.0/20140620_1.3.46.670589.16.11.8.34254330145.20140603.134057.0.zip .
adding: .studiesToExportSend.txt.swp^C
zip error: Interrupted (aborting)
+ sudo chown : /home/support/export/1.3.46.670589.16.11.8.34254330145.20140603.134057.0/1.3.46.670589.16.11.8.34254330145.20140603.134057.0.zip
[sudo] password for support:
This line is your problem:
zip -r ~/export/"${studyinstanceuids[#]}"/20140620_"${studyinstanceuids[#]}".zip .
You're attempting to create a zip file called ~/export/"${studyinstanceuids[#]}"/20140620_"${studyinstanceuids[#]}".zip (good) with all of the contents in the current directory . (bad).
You need to change the . to be the folder you want zipped.
This program I use has it's own variables to set when you run it, so I want to set those variables and then greping the output then storing it inside a variable. However, I don't know how to go about this the correct way. The idea I have doesn't work. The focus is on lines 7 through 14.
1 #!/usr/local/bin/bash
2 source /home/gempak/NAWIPS/Gemenviron.profile
3 FILENAME="$(date -u '+%Y%m%d')_sao.gem"
4 SFFILE="$GEMDATA/surface/$FILENAME"
5 echo -n "Enter the station ID: "
6 read -e STATION
7 OUTPUT=$(sflist << EOF
8 SFFILE = $SFFILE
9 AREA = #$STATION
10 DATTIM = all
11 SFPARM = TMPF;DWPF
12 run
13 exit
14 EOF)
15 echo $OUTPUT
But I get this:
./listweather: line 7: unexpected EOF while looking for matching `)'
./listweather: line 16: syntax error: unexpected end of file
Putting together everyone's answers, I came across a working solution myself. This code works for me:
#!/usr/local/bin/bash
source /home/gempak/NAWIPS/Gemenviron.profile
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=$(sflist << EOF
SFFILE = $SFFILE
AREA = #$STATION
DATTIM = ALL
SFPARM = TMPF;DWPF
run
exit
EOF
)
echo $OUTPUT | grep $STATION
Thanks everyone!
I'd put your program to run in a separate .sh script file, and then run the script from your first file, passing the arguments you want to pass as command line arguments. That way you can test them separately.
You could also do it in a function, but I like the modularity of the second script. I don't udnerstand exactly what you are trying to do above, but something like:
runsflist.sh:
#!/bin/bash
FILENAME="$(date -u '+%Y%m%d')_sao.gem"
SFFILE="$GEMDATA/surface/$FILENAME"
AREA = #$STATION
DATTIM = all
SFPARM = TMPF;DWPF
grep $STATION | sflist
main.sh:
#!/bin/bash
echo -n "Enter the station ID: "
read -e STATION
OUTPUT=`runsflist.sh`
echo $OUTPUT
If sflist needs interaction, I'd try something like this:
SFFILE=$(
( echo SFFILE = "$SFFILE"
echo AREA = "#$STATION"
echo DATTIM = all
echo SFPARM = TMPF;DWPF
echo run
cat
) | sflist)
Unfortunately, you have to type exit as part of the interaction.