simple cp $file1 $file2 script not working? - bash

I tried searching for this question but I couldn't find a thread specifically like this one. I am trying to do a practice script where you enter in a source and a destination and the program copies the files for you.
./testscript
"name of file to copy?" file1
"to be copied to?" file2
"file1 has been copied to file2"
So far I have this:
#!bin/bash
echo -e 'Enter file name of file you wish to copy'
read $FILE1
echo -e 'Enter the file you wish to copy to'
read $FILE2
if cp $FILE1 $FILE2
then echo -e 'Copy was successful'
else echo -e 'Copy was unsuccessful'
fi
The program error is saying bad interpreter. I don't really understand, it looks okay from my end.

The path you supplied as interpreter is not absolute (missing '/').
I suggest changing #!bin/bash to #!/usr/bin/env bash
.
See The difference between "#! /usr/bin/env bash" and "#! /usr/bin/bash"? for details.

You have provided incorrect path to the interpreter. You are probably missing a forward slash in the beginning.
The shebang statement should say: #!/bin/bash (or whatever the correct path is)

Related

Checkin if a Variable File is in another directory

I'm looking to check if a variable file is in another directory, and if it is, stop the script from running any farther. So far I have this:
#! /bin/bash
for file in /directory/of/variable/file/*.cp;
do
test -f /directory/to/be/checked/$file;
echo $?
done
I ran an echo of $file and see that it includes the full path, which would explain why my test doesn't see the file, but I am at a loss for how to move forward so that I can check.
Any help would be greatly appreciated!
Thanks
I think you want
#! /bin/bash
for file in /directory/of/variable/file/*.cp ; do
newFile="${file##*/}"
if test -f /directory/to/be/checked/"$newFile" ; then
echo "/directory/to/be/checked/$newFile already exists, updating ..."
else
echo "/directory/to/be/checked/$newFile not found, copying ..."
fi
cp -i "$file" /directory/to/be/checked/"$newFile"
done
Note that you can replace cp -i with mv -i and move the file, leaving no file left behind in /directory/of/variable/file/.
The -i option means interrogate (I think), meaning if the file is already there, it will ask you overwrite /directory/to/be/checked/"$newFile" (or similar) to which you must reply y. This will only happen if the file already exists in the new location.
IHTH
The command basename will give you just the file (or directory) without the rest of the path.
#! /bin/bash
for file in /directory/of/variable/file/*.cp;
do
test -f /directory/to/be/checked/$(basename $file);
echo $?
done

Looping though all .sh files in a directory to find specific text in each one

I have a bunch of .sh files in a directory. I need to find out how many stored procedures each one of them calls. What would be the best way to do that?
I'm REALLY new with bash scripts so this is all very new to me. From what I looked online I hacked up a starting point (I think) but I have no idea how I would open each file, and find "something.sql" in it and then out put number of times that was found in each file.
Here's what I have:
#!/bin/sh
for i in 'ls *.sh'
echo -e "\n **** START****"
do
echo -e " \n Filename: $i"
done
echo -e "\n **** END ****"
done
Thanks for any help!
Try this:
grep -nc sql *.sh
See how that moves you. You can add -i if you name sql files in as file.SQL too. Or if they all have a .sql extension.
grep -nc '\.sql' *.sh
For you comment you added, try this:
for i in *.sh
grep -Hc '\.sql' $i
grep '\.sql' $i
done

bash: grep only returns "Is a directory" when searching for a file that exists

Up until recently, I was able to have a script make sure a certain file exists within a certain directory before continuing.
Now, the script either does not find the file or, when grep works, just returns "grep: /Users/user/Downloads: Is a directory" when finished."
The file is exists in the directory, but grep doesn't want to interact with it anymore. This is the sort of thing I'm working with:
if grep -q 'file.bin' ~/Downloads; then echo "It works!" exit 1 fi
Any advice would be appreciated. Thanks.
You are asking grep to search for a string (file.bin) in a file called ~/Downloads...which is a directory. So the error you are seeing is accurate; grep only operates on files, not on directories.
If you want to see if a file exists, you probably just want to use the standard shell tests for files:
if [ -f ~/Downloads/file.bin ]; then
echo "It exists!"
fi
You would use grep to see if a string exists in a file:
if grep -q "a string" ~/Downloads/file.bin; then
echo "The file contains the string"
fi

bash save last user input value permanently in the script itself

Is it possible to save last entered value of a variable by the user in the bash script itself so that I reuse value the next time while executing again?.
Eg:
#!/bin/bash
if [ -d "/opt/test" ]; then
echo "Enter path:"
read path
p=$path
else
.....
........
fi
The above script is just a sample example I wanted to give(which may be wrong), is it possible if I want to save the value of p permanently in the script itself to so that I use it somewhere later in the script even when the script is re-executed?.
EDIT:
I am already using sed to overwrite the lines in the script while executing, this method works but this is not at all good practice as said. Replacing the lines in the same file as said in the below answer is much better than what I am using like the one below:
...
....
PATH=""; #This is line no 7
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
name="$(basename "$(test -L "$0" && readlink "$0" || echo "$0")")";
...
if [ condition ]
fi
path=$path
sed -i '7s|.*|PATH='$path';|' $DIR/$name;
Someting like this should do the asked stuff :
#!/bin/bash
ENTERED_PATH=""
if [ "$ENTERED_PATH" = "" ]; then
echo "Enter path"
read path
ENTERED_PATH=$path
sed -i 's/ENTERED_PATH=""/ENTERED_PATH='$path'/g' $0
fi
This script will ask user a path only if not previously ENTERED_PATH were defined, and store it directly into the current file with the sed line.
Maybe a safer way to do this, would be to write a config file somewhere with the data you want to save and source it . data.saved at the begining of your script.
In the script itself? Yes with sed but it's not advisable.
#!/bin/bash
test='0'
echo "test currently is: $test";
test=`expr $test + 1`
echo "changing test to: $test"
sed -i "s/test='[0-9]*'/test='$test'/" $0
Preferable method:
Try saving the value in a seperate file you can easily do a
myvar=`cat varfile.txt`
And whatever was in the file is not in your variable.
I would suggest using the /tmp/ dir to store the file in.
Another option would be to save the value as an extended attribute attached to the script file. This has many of the same problems as editing the script's contents (permissions issues, weird for multiple users, etc) plus a few of its own (not supported on all filesystems...), but IMHO it's not quite as ugly as rewriting the script itself (a config file really is a better option).
I don't use Linux, but I think the relevant commands would be something like this:
path="$(getfattr --only-values -n "user.saved_path" "${BASH_SOURCE[0]}")"
if [[ -z "$path" ]]; then
read -p "Enter path:" path
setfattr -n "user.saved_path" -v "$path" "${BASH_SOURCE[0]}"
fi

Shell scripting debug help - Iterating through files in a directory

#!/bin/sh
files = 'ls /myDir/myDir2/myDir3/'
for file in $files do
echo $file
java myProg $file /another/directory/
done
What i'm trying to do is iterate through every file name under /myDir/myDir2/myDir3/, then use that file name as the first argument in calling a java program (second argument is "/another/directory")
When I run this script: . myScript.sh
I get this error:
-bash: files: command not found
What did I do wrong in my script? Thanks!
Per Neeaj's answer, strip off the whitespace from files =.
Better yet, use:
#!/bin/sh -f
dir=/myDir/MyDir2/MyDir3
for path in $dir/*; do
file=$(basename $path)
echo "$file"
java myProg "$file" arg2 arg3
done
Bash is perfectly capable of expanding the * wildcard itself, without spawning a copy of ls to do the job for it!
EDIT: changed to call basename rather than echo to meet OP's (previously unstated) requirement that the path echoed be relative and not absolute. If the cwd doesn't matter, then even better I'd go for:
#!/bin/sh -f
cd /myDir/MyDir2/MyDir3
for file in *; do
echo "$file"
java myProg "$file" arg2 arg3
done
and avoid the calls to basename altogether.
strip off the whitespace in and after files = as files=RHS of assignment
Remove the space surrounding the '=' : change
files = 'ls /myDir/myDir2/myDir3/'
into:
files='ls /myDir/myDir2/myDir3/'
and move the 'do' statement to its own line:
for file in $files
do
....
quote your variables and no need to use ls.
#!/bin/sh
for file in /myDir/myDir2/*
do
java myProg "$file" /another/directory/
done

Resources