How to execute commands read from the txt file using shell? [duplicate] - linux

This question already has answers here:
Run bash commands from txt file
(4 answers)
Closed 4 years ago.
I tried to execute commands read it from txt file. But only 1st command is executing, after that script is terminated. My script file name is shellEx.sh is follows:
echo "pwd" > temp.txt
echo "ls" >> temp.txt
exec < temp.txt
while read line
do
exec $line
done
echo "printed"
if I keep echo in the place of exec, just it prints both pwd and ls. But i want to execute pwd and ls one by one.
o/p am getting is:
$ bash shellEx.sh
/c/Users/Aditya Gudipati/Desktop
But after pwd, ls also need to execute for me.
Anyone can please give better solution for this?

exec in bash is meant in the Unix sense where it means "stop running this program and start running another instead". This is why your script exits.
If you want to execute line as a shell command, you can use:
line="find . | wc -l"
eval "$line"
($line by itself will not allow using pipes, quotes, expansions or other shell syntax)
To execute the entire file including multiline commands, use one of:
source ./myfile # keep variables, allow exiting script
bash myfile # discard variables, limit exit to myfile

A file with one valid command per line is itself a shell script. Just use the . command to execute it in the current shell.
$ echo "pwd" > temp.txt
$ echo "ls" >> temp.txt
$ . temp.txt

Related

How do I search for bash script files without having a specific extension within a folder?

I want to find bash script files under folders in Array.
But bash script files do not have a specified extension.
I wrote something like this:
for i in "${array[#]}"
do
# Here I will write the condition that the file is found in the folder $k
done
If your scripts have #!/bin/bash or #!/bin/sh in their first line (as they should), then you can use the file command to check if a file is a script or not.
For example, take this script:
#!/bin/bash
echo "I am a script!"
Output of file filename.sh will be filename.sh: Bourne-Again shell script, ASCII text executable, which is indicating it is a shell script. Note that the file command does not use the extension of the file to indicate its format, but uses the content of it.
If you don't have those lines at the beginning of your file, You can try to run every file (command: bash filename.ext) and the check if it was run successfully or not by checking the value of the variable ${?}. This is not a clean method but it sure can help if you have no other choices.
The file command determines a file type.
e.g
#!/bin/bash
arr=(~/*)
for i in "${arr[#]}"
do
type=`file -b $i | awk '{print $2}'`
if [[ $type = shell ]];then
echo $i is a shell script
fi
done

How to redirect STDOUT and STDERR in a file for every command? [duplicate]

This question already has answers here:
How to redirect output of an entire shell script within the script itself?
(6 answers)
Closed 3 years ago.
I'm trying to store both STDOUT and STDERR from the terminal (and if possible STDIN given by user) in a file for every command.
So i started creating a trap function to execute every command in a edited manner like:
shopt -s extdebug
preexec_invoke_exec () {
[ -n "$COMP_LINE" ] && return # do nothing if completing
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
eval `history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"` |& tee ~/recent_output.txt
return 1 # This prevent executing of original command
}
trap 'preexec_invoke_exec' DEBUG
and saving the above file and executing
source file.sh
This did the work what i wanted but stopped some commands from executing like
cd ..
The reason for this was piping creates a sub-shell and then executes every command in it. So the main shell remains unaffected.
Even the script functionality of bash i.e
script ~/recent_output.txt
worked but only gives output after you do exit in in terminal
So, basically i want to store/get the output of previous command executed in the bash terminal. You can help me with any language (golang,python...).
It is possible to capture commands, stderr and stdout of a bash script (say x.sh), using:
bash -x x.sh 2> >(tee err.txt) | tee out.txt
The err.txt will capture the executed commands (prefixed with '+'), and the stderr of each command. The out.txt will capture the output

Errors "No such file or directory" ,"command not found" seen while running my shell script

The contents of my script
`sqlline.py tpxxx.entexxx.org <<END
!outputformat csv
!record /ap_data/DD3/Rawf/Raw_f_$1_$2.csv
select column1,column2,column3,column4 from DD3_vxxv_$1.DD3_vv_RAW_DATA where v_id=$3 and period=$4;
!record
!quit
END;`
`sed -i '1d;$d' /ap_data/DD3/Rawf/Raw_f_$1_$2.csv;
sed -i "s/'//g" /ap_data/DD3/Rawf/Raw_f_$1_$2.csv;
cd /ap_data/D2O/RawDownload/
zip Raw_f_$1_$2.zip Raw_f_$1_$2.csv;
scp Raw_f_$1_$2.zip txxx#daxxxx.entexxx.org:/opt/cdar/common/D2O/TabUpload/;
rm Raw_f_$1_$2.csv Raw_f_$1_$2.zip;`
On executing the script:
./rawfile.sh: line 7: 0/?: No such file or directory
./rawfile.sh: line 13: adding:: command not found
The script gives correct output. But still shows the errors "No such file or directory", "command not found"
My file permission is: -rwxrwxrwx
Your script has backquotes around two main executable sections.
Backquotes cause the content within to be executed in a subshell and substituted back into your script. This means that in your case, your script is executing TWO commands. One of them is the output of the first backquoted expression, and the other is the output of the second backquoted expression.
For example:
$ `echo hello`
bash: hello: command not found
$ `echo echo hello`
hello
What's happening here is that the first echo command generates output which is substituted into your command line, making the command line evaluated by the shell simply "hello" .. which is not a command. The second command line prints "echo hello", which is a valid command line and evaluates to something that prints "hello".
Remove the backquotes from around your two main statements, and just execute the commands directly.
#!/bin/sh
sqlline.py tpxxx.entexxx.org <<END
!outputformat csv
!record /ap_data/DD3/Rawf/Raw_f_$1_$2.csv
select column1,column2,column3,column4 from DD3_vxxv_$1.DD3_vv_RAW_DATA where v_id=$3 and period=$4;
!record
!quit
END
sed -i '1d;$d' /ap_data/DD3/Rawf/Raw_f_$1_$2.csv
sed -i "s/'//g" /ap_data/DD3/Rawf/Raw_f_$1_$2.csv
cd /ap_data/D2O/RawDownload/
zip Raw_f_$1_$2.zip Raw_f_$1_$2.csv
scp Raw_f_$1_$2.zip txxx#daxxxx.entexxx.org:/opt/cdar/common/D2O/TabUpload/
rm Raw_f_$1_$2.csv Raw_f_$1_$2.zip

Difference between executing a script with 'bash cd.sh' and 'source cd.sh'? [duplicate]

This question already has answers here:
What is the difference between using `sh` and `source`?
(5 answers)
Closed 7 years ago.
Explain the difference between executing a script with bash cd.sh and source cd.sh
cd.sh contains:
#!/bin/sh
cd /tmp
bash execute the script in a child shell that cannot modify the environment of the invoking shell while source executes the script in the current shell:
test.sh
#!/bin/sh
export MY_NAME=chucksmash
echo $MY_NAME
Running test.sh:
chuck#precision:~$ bash test.sh
chucksmash
chuck#precision:~$ echo $MY_NAME
chuck#precision:~$ source test.sh
chucksmash
chuck#precision:~$ echo $MY_NAME
chucksmash
chuck#precision:~$
In bash, commands that look like source script.sh (or . script.sh) run the script in the current shell, regardless of the #! line.
Therefore, if you have a script (named script.sh in this example):
#!/bin/bash
VALUE=1
cd /tmp
This would print nothing (because VALUE is null) and not change your directory (because the commands were executed in another instance of bash):
bash script.sh
echo $VALUE
This would print 1 and change your directory to /tmp:
source script.sh
echo $VALUE
If you instead had this script (named script.py in this example):
#!/usr/bin/env python
print 'Hello, world"
This would give a WEIRD bash error (because it tries to interpret it as a bash script):
source shell.py
This would *also *give a WEIRD bash error (because it tries to interpret it as a bash script):
bash shell.py
This would print Hello, world:
./shell.py # assuming the execute bit it set

Shell Script and Command Line Discrepancies

I was wondering if there were specific permissions that were associated with a shell script or if some variable references are taken as being syntactically different.
I tried my short renaming script below:
#!/bin/bash
echo "Starting Renaming Script"
for file in ./*
do
rename=$(echo $file | sed 's/\(img_\)\([0-9]*-[0-9]*\)-\([0-9]*\)_\([0-9]*\).jpg/newyears_20\3-\2_0\4.jpg/')
mv $file $rename
done
All it does is rename a few files, but I noticed that it would work on the command line, but not in the shell script when I ran sh rename.sh
I got the error
rename.sh: syntax error at line 7: `rename=$' unexpected
Is variable assignment handled differently in the shell than on the command line?
Different shells handle commands differently. Your script is a bash script (as identified on the first line #!/bin/bash), therefore it needs to be run by bash, not sh.
bash rename.sh

Resources