Grep and other programs not found in script [duplicate] - bash

This question already has answers here:
"ls: not found" after running "read PATH"
(2 answers)
Getting "command not found" error in bash script
(6 answers)
Closed 12 months ago.
I am trying to gather all of my TODOs and make one file out of them.
#!/bin/bash
# Script for getting all TODOS
PATH="~/documents/obsidian-notes/"
OUTPUT="/home/fish/documents/obsidian-notes/TODO.md"
echo "#TODO" > $OUTPUT
grep -hr --exclude-dir=plugins "\bTODO\b:.*" $PATH | awk '{print $0,"\n"}' >> $OUTPUT
If I run each line in my prompt it works perfectly. When I add them to a script and make it executable and run it I get
./obtodo.sh: line 10: grep: command not found
./obtodo.sh: line 10: awk: command not found
./obtodo.sh: line 12: chown: command not found
I tried running as sudo and I made the script executable with chmod a+x

$PATH is a special variable to the shell. It defines the list of directories to be searched when executing subcommands.
Bash won't know where grep, awk or chown are. Please use different variable name instead of $PATH.
Try
#!/bin/bash
# Script for getting all TODOS
xPATH="~/documents/obsidian-notes/"
OUTPUT="/home/fish/documents/obsidian-notes/TODO.md"
echo "#TODO" > $OUTPUT
grep -hr --exclude-dir=plugins "\bTODO\b:.*" $xPATH | awk '{print $0,"\n"}' >> $OUTPUT

Related

Checking file existence in Bash using commandline argument

How do you use a command line argument as a file path and check for file existence in Bash?
I have the simple Bash script test.sh:
#!/bin/bash
set -e
echo "arg1=$1"
if [ ! -f "$1" ]
then
echo "File $1 does not exist."
exit 1
fi
echo "File exists!"
and in the same directory, I have a data folder containing stuff.txt.
If I run ./test.sh data/stuff.txt I see the expected output:
arg1=data/stuff.txt
"File exists!"
However, if I call this script from a second script test2.sh, in the same directory, like:
#!/bin/bash
fn="data/stuff.txt"
./test.sh $fn
I get the mangled output:
arg1=data/stuff.txt
does not exist
Why does the call work when I run it manually from a terminal, but not when I run it through another Bash script, even though both are receiving the same file path? What am I doing wrong?
Edit: The filename does not have spaces. Both scripts are executable. I'm running this on Ubuntu 18.04.
The filename was getting an extra whitespace character added to it as a result of how I was retrieving it in my second script. I didn't note this in my question, but I was retrieving the filename from folder list over SSH, like:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1)
Essentially, I wanted to get the filename of the most recent file in a directory on a remote server. Apparently, head includes the trailing newline character. I fixed it by changing it to:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1 | tr -d '\n' | tr -d '\r')
Thanks to #bigdataolddriver for hinting at the problem likely being an extra character.

Unable to cat a data file into a script file (bash) on terminal command line [duplicate]

This question already has answers here:
Terminal - command not found
(2 answers)
Closed 3 years ago.
Im new to bash, and I am unable to cat a file and use the pipe command on the terminal using bash.
This is what ive tried on the terminal command line
$ cat data | readlooptest
however i always get this message when i use the pipe |
-bash: readlooptest: command not found
I have a Script named readlooptest, and a data file
script contents of readlooptest
#!/bin/bash
read myLine
sum=0
for i in $myLine
do
sum=`expr $sum + $i`
done
echo "sum is: $sum"
data file contents are
6 4 4 7 7
So once the commands are entered in terminal, the output should be
$ chmod +x readlooptest
$ cat data | readlooptest
sum is : 28
However I get
-bash: readlooptest: command not found
If readlooptest is not installed in one of your $PATH directories, you have to give the path to it to run it.
So for your piped cat, if you are cd in the same directory as readlooptest:
cat data | ./readlooptest
This has nothing to do with piping or cat. The actual problem is that you need to specify where readlooptest is, since it's not in your PATH. If it's in the working directory, simply add ./ to the start:
$ cat data | ./readlooptest

"basename" used in subshell returns "command not found" [duplicate]

This question already has an answer here:
Find "command not found" when executed in bash loop
(1 answer)
Closed 4 years ago.
When running this script:
#!/bin/sh -ex
if [[ $# -ne 1 ]]; then
echo "./import-public-ssh-key.sh <absolute path to public key>"
exit 1;
fi
PATH=$1
KEY=$(basename ${PATH})
I get:
./import-public-ssh-key.sh: line 9: basename: command not found
without the subshell basename works:
$ basename /Users/mles/.ssh/id_rsa.pub
id_rsa.pub
Why is basename not working in the subshell? I'm on a mac if this is relevant.
You reset the PATH. Don't do that. The shell searches all the directories listed in PATH, and you have changed it so that PATH no longer contains the directory that contains basename.

Error with simple shell script [duplicate]

This question already has answers here:
I am getting error "array.sh: 3: array.sh: Syntax error: "(" unexpected"
(3 answers)
Closed 6 years ago.
I wrote a shell script which automatically set up environment
#!/bin/sh
set path=(/dv/project/ $path)
I change the execution bit by
chmod +x init.sh
When I run it as
./init.sh
It prompted me with error
./init.sh: line 3: syntax error near unexpected token `('
./init.sh: line 3: `set path=(/dv/project/ $path)'
What could be the problem here? Thanks!
If using of set isn't required, just try this:
#!/bin/bash
path=(/dv/project/ $path)
As I have noticed, you're trying to extend your $PATH environment variable, right? There is a better way. Try this approach:
# Extend $PATH without duplicates
function _extend_path() {
if ! $( echo "$PATH" | tr ":" "\n" | grep -qx "$1" ) ; then
PATH="$1:$PATH"
fi
}
# Add custom bin to $PATH
[ -d ~/.bin ] && _extend_path "$HOME/.bin"

Bash script not working on a new dedicated server

Recently I have migrated to the new dedicated server which is running on the same operating system - FreeBSD 8.2. I got a root account access and all permissions have been set properly.
My problem is that, the bash script I was running on the old server doesn't works on the new machine, the only error appearing while running the script is:
# sh script.sh
script.sh: 3: Syntax error: word unexpected (expecting ")")
Here is the code itself:
#!/usr/local/bin/bash
PORTS=(7777:GAME 11000:AUTH 12000:DB)
MESSG=""
for i in ${PORTS[#]} ; do
PORT=${i%%:*}
DESC=${i##*:}
CHECK=`sockstat -4 -l | grep :$PORT | awk '{print $3}' | head -1`
if [ "$CHECK" -gt 1 ]; then
echo $DESC[$PORT] "is up ..." $CHECK
else
MESSG=$MESSG"$DESC[$PORT] wylaczony...\n"
if [ "$DESC" == "AUTH" ]; then
MESSG=$MESSG"AUTH is down...\n"
fi
if [ "$DESC" == "GAME" ]; then
MESSG=$MESSG"GAME is down...\n"
fi
if [ "$DESC" == "DB" ]; then
MESSG=$MESSG"DB is down...\n"
fi
fi
done
if [ -n "$MESSG" ]; then
echo -e "Some problems ocurred:\n\n"$MESSG | mail -s "Problems" yet#another.com
fi
I don't really code in bash, so I don't know why this happend...
Bourne shell (sh) doesn't support arrays, that's why you're running into this error when you use
sh script.sh
Use bash instead
bash script.sh
Note: I suspect that sh script.sh worked on the old server because sh is linked to bash there.
also you shouldn't need to run it through sh (that's what the
#!
on the first line is for - the OS will run the remainder of the line as a command and pass the contents of the file for it to interpret). Just make the script executable:
chmod +x script.sh
and then you can just run it directly without the sh in front of the name.
It's possible that the default shell is not bash and so by running it through sh you're interpreting it with a different shell which is then giving the error
The code looks good. It is likely that your new dedicated server is running older version of Bash than your last server. Or maybe /usr/local/bin/bash is pointing towards older version.
Run
$ which bash
if the output is other than /usr/local/bin/bash then change the first shebang line to the newer path, if it still does not work
Try replacing third line:
PORTS=(7777:GAME 11000:AUTH 12000:DB)
with
PORTS=('7777:GAME' '11000:AUTH' '12000:DB')
and rerun the script.
If it still does not work then post the BASH version here by running
$ bash --version
try with facing and trailing spaces
PORTS=( 7777:GAME 11000:AUTH 12000:DB )

Resources