command not found when executing nested bash scripts - linux

I am having a bash script that is executing another bash script:
ex:
script name "rotator" is calling script name "s3-get" like below
!# /bin/bash
...
./s3-get {and params here}
All commands as "cat", "basename" etc. run correctly here
Within the "s3-get" script there is code as:
!# /bin/bash
cat > /dev/null << EndOfLicense
...
readonly weAreKnownAs="$(basename $0)"
...
main "$#"
So, if I simply execute the s3-get script directly from shell, it runs perfectly. When I try to execute it from "rotator" script, I get the error "cat: command not found". I can fix this by changing "cat" with "/bin/cat" just that I don't think this is correct since, as I stated above, the script runs correctly when executed as standalone. If I fix the "cat" command as above, the next error that raises is "basename: command not found", then "main: command not found"
I am pretty new to shell programming, so any help is appreciated.
Thank you

Try $ echo 'export PATH=$PATH:/root/scripts/RotateVideos' >> ~/.bashrc && source ~/.bashrc in the command line and then just call it using s3-get in your script. Alternatively use cd /root/scripts/RotateVideos && bash s3-get.

Related

Self-defined bash command works in terminal but not in script

I have two scripts:
fail_def.sh:
#!/bin/bash -eu
function fail() {
echo -e "$(error "$#")"
exit 1
}
bla.sh:
#!/bin/bash -eu
fail "test"
After source fail_def.sh, I can use the fail command without any problems in the terminal. However, when I call bla.sh, I always get line 2: fail: command not found.
It doesn't matter whether I call it via ./bla.sh or bash bla.sh or bash ./bla.sh, the error remains.
Adding source fail_def.sh to the beginning of bla.sh solves the problem, but I'd like to avoid that.
I'm working on an Ubuntu docker container running on a Mac, in case that is relevant.
I tried to google that problem and found some similar problems, but most of them seem to be connected to either not sourcing the file or mixing up different shell implementations, neither of which seems to be the case here.
What do I have to do to get the fail command to work inside the script?
It is expected!
The shell runs the script run with an she-bang separator always as a separate process and hence on a different shell namespace. The new shell in which your script runs does not have the function source'd.
For debugging such information, add a line echo $BASHPID which prints the process id of the current bash process on the bla.sh script after the line #!/bin/bash -eu and a test result produced
$ echo $BASHPID
11700
$ bash bla.sh
6788
fail.sh: line 3: fail: command not found
They scripts you have run on separate process where the imported functions are not shared between. One of the ways would be to your own error handling on the second script and by source-ing the second script. On the second script
$ cat fail.sh
echo $BASHPID
set -e
fail "test"
set +e
Now running it
$ source fail.sh
11700
11700
bash: error: command not found
which is obvious as error is not a shell built-in which is available. Observe the process id's same on the above case.

Bash script to go to directory and perform commands gives "Command not found" [duplicate]

This question already has answers here:
How to use aliases defined in .bashrc in other scripts?
(6 answers)
Closed 2 years ago.
My alias defined in a sample shell script is not working. And I am new to Linux Shell Scripting.
Below is the sample shell file
#!/bin/sh
echo "Setting Sample aliases ..."
alias xyz="cd /home/usr/src/xyz"
echo "Setting done ..."
On executing this script, I can see the echo messages. But if I execute the alias command, I see the below error
xyz: command not found
am I missing something ?
source your script, don't execute it like ./foo.sh or sh foo.sh
If you execute your script like that, it is running in sub-shell, not your current.
source foo.sh
would work for you.
You need to set a specific option to do so, expand_aliases:
shopt -s expand_aliases
Example:
# With option
$ cat a
#!/bin/bash
shopt -s expand_aliases
alias a="echo b"
type a
a
$ ./a
# a is aliased to 'echo b'
b
# Without option
$ cat a
#!/bin/bash
alias a="echo b"
type a
a
$ ./a
./a: line 3: type: a: not found
./a: line 4: a: command not found
reference: https://unix.stackexchange.com/a/1498/27031 and https://askubuntu.com/a/98786/127746
sourcing the script source script.sh
./script.sh will be executed in a sub-shell and the changes made apply only the to sub-shell. Once the command terminates, the sub-shell goes and so do the changes.
OR
HACK: Simply run following command on shell and then execute the script.
alias xyz="cd /home/usr/src/xyz"
./script.sh
To unalias use following on shell prompt
unalias xyz
If you execute it in a script, the alias will be over by the time the script finishes executing.
In case you want it to be permanent:
Your alias is well defined, but you have to store it in ~/.bashrc, not in a shell script.
Add it to that file and then source it with . .bashrc - it will load the file so that alias will be possible to use.
In case you want it to be used just in current session:
Just write it in your console prompt.
$ aa
The program 'aa' is currently not installed. ...
$
$ alias aa="echo hello"
$
$ aa
hello
$
Also: From Kent answer we can see that you can also source it by source your_file. In that case you do not need to use a shell script, just a normal file will make it.
You may use the below command.
shopt -s expand_aliases
source ~/.bashrc
eval $command
Your alias has to be in your .profile file not in your script if you are calling it on the prompt.
If you put an alias in your script then you have to call it within your script.
Source the file is the correct answer when trying to run a script that inside has an alias.
source yourscript.sh
Put your alias in a file call ~/.bash_aliases and then, on many distributions, it will get loaded automatically, no need to manually run the source command to load it.

How to run shell script without typing bash (bash command error:mapfile not found)

I am using mapfile -t to obtain content of a text file and assign it to array.
In Jenkins it works fine where it will prompt steps and what command executed in console output .When I try to run in local console for example putty it prompts.
mapfile: not found [No such file or directory]
I know that mapfile is a bash command is and I am able to run the shell program after typing bash and executing the script.Is there anyway that I don't need to type bash in order to run the program ?I include #!/bin/bash -x on top of the script it still display the same error .The reason I don't want to type bash and execute the script is due to that it did not show what are the errors when the script dies.It did not display the error handling process that was in the script and it did not display output when it runs the command.
Please open a new file called script in a text editor. Type your program in:
#!/bin/bash -x
set -e
item=$1
if [ $item = '-database' ] then
mapfile -t DATA < $DATA_FILES
fi
save the file, execute chmod u+x and then
./script "-database"
to run it.
That's it.
However, that script will print nothing.

Exporting a script variable using `sh -cx`

I'm trying to export a variable from a script in the following manner:
sh -xc "<script here>"
But cannot get it to work at all. I've tried several techniques such as:
sh -xc "./xxx.sh"(exporting a variable yyy from the file itself)
sh -xc "./xxx.sh && export yyy=1"
(had xxx.sh exit 0)
sh -xc ". ./xxx.sh"
As well as several permutations of the above, but no dice on any of them.
Unfortunately, I must conform to the sh -xc "<script here>" style. Any script I execute will be placed inside of the quotations, file and/or command(s). There's no way around this.
Is what I'm asking even possible? If so, how?
Thanks!
You can't do an export through a shell script, because a shell script runs in a child shell process, and only children of the child shell would inherit the export.
The reason for using source is to have the current shell execute the commands
It's very common to place export commands in a file such as .bashrc which a bash will source on startup (or similar files for other shells)
But you can do as follows:
shell$ cat > script.sh
#!/bin/sh
echo export myTest=success
chmod u+x script.sh
And then have the current shell execute that output
shell$ `./script.sh`
shell$ echo $myTest
success
shell$ /bin/sh
$ echo $myTest
success

Simple bash Linux script to run stored procedure

I need a bash/Linux shell script which will run my stored procedure only on Wednesday.
I am new to Bash shell scripting.
Below is what I came up with:
test.sh
#!/bin/bash
MYSQL="/usr/bin/mysql --compress -hlocalhost -utest -ptest test";
dayofweek=`date +%a`
#if [ ${dayofweek} ='Wed' ] ; then ${MYSQL} -e "CALL testSummary();"; fi ;
When I run it:
sh test.sh, it says:
: command not found
Thank you.
how about run CALL testSummary() from mysql prompt?
besides [ ${dayofweek} ='Wed' ] should be [ ${dayofweek} = 'Wed' ], no other issue with your script
I created a simple testSummary procedure, it only print value of select 1 + 1, running your script gives me the correct output.
I don't see why you'd be getting the command not found error.
Couldn't the -e "CALL testSummary();" part be what's giving it?
Anyway:
You don't need
#!/bin/bash
If you're running it with
$ sh test.sh
Now if you made that script executable with
$ chmod +x test.sh
then doing $ ./test.sh would be tantamount to calling /bin/bash test.sh.
Make up your mind as to whether you want to use bash or sh. They are different.
If you want to run something periodically on Linux, you might want to take a look at this:
https://help.ubuntu.com/community/CronHowto

Resources