Bash script that will execute a program over all files in a directory - linux

Writing a bash script that will execute the program 'main' over all the files in the directory 'allfiles'. Main is an executable. The results are then directed to the file 'output.dat'.
Whenever I run the bash script I get the error "./main: no such file or directory". The bash script, main, and 'allfiles' directory are all in the '/home/directory/'. I'm not certain as to why i'm getting this error, or if i'm writing the bash script correctly. Any help is greatly appreciated.
#!/bin/bash
for file in /home/directory/allfiles/*
do
./main $file >> output.dat
done
edit: should clarify that 'main' is an executable file produced from a makefile

If you're not in /home/directory when you run the script, then it won't be able to find main. Try
#!/bin/bash
for file in /home/directory/allfiles/*
do
/home/directory/main $file >> output.dat
done
Additionally, if main is not executable, you'll have to get bash to call it manually. Use bash /home/directory/main $file for that, or make main executable using chmod +x main.

I prefer using find in this case of use. You can manage using subdirs ;)
#!/bin/bash
main=./main
basedir=/home/directory/allfiles/
outFile=output.dat
for file in $(find $basedir -type f)
do
$main $file >> $outFile
done

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

What is the difference between ./myShellScript and ~/myShellScript

I am beginner in learning shell script, I found a way to run the the script file from anywhere in file system with '~'
This is my shell script
myShellScript
#! /bin/bash
echo $(date): $* >> ~/notes.txt
echo $(date): $* >> ./notes.txt
And I run the ./myShellScript "write date to file"
I am trying to understand accessing file structure ./ and ~/
./ is for current directory
~/ for home directory

Linux shell script to copy last lines of a file in a directory to append to a file in another directory

I have written the below shell script to copy the last lines of a file in a directory to append to a file in another directory
cd /opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/Lg2Logs
GrinderLG1='rm101sys1lweb22'
GrinderLg2='rm101sys1lweb23'
fileCount=$(ls -l|wc -l)
echo $fileCount
for (( c=0; c<=$fileCount-2; c++ ))
do
Lines=$(more $GrinderLg2"-"$c"-data.log"|wc -l)
Lines1=`expr $Lines - 1`
`"tail -"$Lines1"f /opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/Lg2Logs/"$GrinderLg2"-"$c"-data.log>>/opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/"$GrinderLG1"-"$c"-data.log"`
#exec $command
done
When I am executing this script it says no such file or directory at tail command. Actually both the files exist. Please help.
`"tail -"$Lines1"f /opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/Lg2Logs/"$GrinderLg2"-"$c"-data.log>>/opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/"$GrinderLG1"-"$c"-data.log"`
change to
tail -"$Lines1"f /opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/Lg2Logs/"$GrinderLg2"-"$c"-data.log>>/opt/grinder/svn/IAVS/GrinderLogs/GrinderBaseLogs/"$GrinderLG1"-"$c"-data.log
should work.
In my setup i have tested as below way
#!/bin/sh
`"tail -10f filename"`
give error filename not found
But
#!/bin/sh
tail -10f filename
This works fine.

When shell scripts echos "*", why it lists the files and directories?

I have written the following shell script to print "*" on the screen but when I execute the script, it lists all the files and directories in the current directory in which script is located. Can someone tell me why the script lists all the files and directories in the current directory?
#!/bin/bash
TEST="*";
echo $TEST
Because there are missing some "" around the $TEST.
Try echo "$TEST".
It prints all the files and folders because the shell, bash in your case, expands the * before passing it to the command.
The solution is simple:
#!/bin/bash
TEST="*";
echo "$TEST"

How to process file names with variables from a list in a file in Bash

I have a file "FileList.txt" with this text:
/home/myusername/file1.txt
~/file2.txt
${HOME}/file3.txt
All 3 files exist in my home directory. I want to process each file in the list from a bash script. Here is a simplified example:
LIST=`cat FileList.txt`
for file in $LIST
do
echo $file
ls $file
done
When I run the script, I get this output:
/home/myusername/file1.txt
/home/myusername/file1.txt
~/file2.txt
ls: ~/file2.txt: No such file or directory
${HOME}/file3.txt
ls: ${HOME}/file3.txt: No such file or directory
As you can see, file1.txt works fine. But the other 2 files do not work. I think it is because the "${HOME}" variable does not get resolved to "/home/myusername/". I have tried lots of things with no success, does anyone know how to fix this?
Thanks,
-Ben
Use eval:
while read file ; do
eval echo $file
eval ls $file
done < FileList.txt
From the bash manpage regarding the eval command:
The args are read and concatenated together into a single command. This command is
then read and executed by the shell, and its exit status is returned as the value of
eval. If there are no args, or only null arguments, eval returns 0.
you will hit "spaces problem" using the for loop with cat. Manipulate IFS, or use a while read loop instead
while read -r line; do eval ls "$line"; done < file
Change "ls $file" to "eval ls $file" to get the shell to do its expansion.

Resources