Error when passing argument to a command in a bash script - bash

I would like to execute a command like this:
#!/bin/sh
`which rvmsudo` `which program` argument
but I get this issue
/usr/bin/env: argument: No such file or directory

Make sure, all of the which statements return valid:
#!/bin/bash
RVMSUDO=`which rvmsudo`
test -z "$RCMSUDO" && exit 1
PROGRAM=`which program`
test -z "$PROGRAM" && exit 2
$RVMSUDO $PROGRAM argument

Related

Inconsistent result using bash script through shell vs cron

I've got the following bash script to check if a string length is nonzero using -n and equals "OK" by converting the variable to uppercase using ${1^^}:
#!/bin/bash
myfunction() {
result=0
if [[ -n $1 && ${1^^} = "OK" ]]; then
result=1
fi
echo $result >> /home/[REDACTED]/mylog
}
myfunction "ok"
myfunction "NO"
I made it executable using:
sudo chmod +x ./test
I then call it with either of the following:
bash ./test
./test
And the file always contains the expected result:
1
0
However, when trying to run from cron and the file contains:
0
0
I set up cron with this command:
sudo crontab -e
And here is the content:
* * * * * /home/[REDACTED]/test
I'm probably overlooking something obvious like syntax or cron environment... any suggestions?
Thanks!
Not sure why, but deleting the first line of the file and retyping has resolved it:
#!/bin/bash
Thanks all for the help!

Customize "command not found" message in Bash

Is there someway to alter the Bash system error message template so that you can print something in addition to the original message? For example:
Macbook Air:~/Public]$ lfe
-bash: lfe: WTF command not found
or
Macbook Air:~/Public]$ lfe
-bash: lfe: #!&**! command not found
Since Bash 4.0, if the search for a command is unsuccessful, the shell searches for a function called command_not_found_handle. If it doesn't exist, Bash prints a message like this and exits with status 127:
$ foo
-bash: foo: command not found
$ echo $?
127
If it does exist, it is called with the command and its arguments as arguments, so if you have something like
command_not_found_handle () {
echo "It's my handle!"
echo "Arguments: $#"
}
in your .bashrc, Bash will react like this:
$ foo bar
It's my handle!
Arguments: foo bar
Most systems have something much more sophisticated in place, though. My Ubuntu, for example, has this in /etc/bash.bashrc:
# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
function command_not_found_handle {
# check because c-n-f could've been removed in the meantime
if [ -x /usr/lib/command-not-found ]; then
/usr/lib/command-not-found -- "$1"
return $?
elif [ -x /usr/share/command-not-found/command-not-found ]; then
/usr/share/command-not-found/command-not-found -- "$1"
return $?
else
printf "%s: command not found\n" "$1" >&2
return 127
fi
}
fi
and this is sourced from /etc/profile. /usr/lib/command-not-found is a Python script that uses some more Python (CommandNotFound) to basically look up packages that are named like the unknown command, or sound similar:
$ sl
The program 'sl' is currently not installed. You can install it by typing:
sudo apt install sl
$ sedd
No command 'sedd' found, did you mean:
Command 'sed' from package 'sed' (main)
Command 'seedd' from package 'bit-babbler' (universe)
Command 'send' from package 'nmh' (universe)
Command 'send' from package 'mailutils-mh' (universe)
sedd: command not found
So if you want simple customization, you can provide your own command_not_found_handle, and if you want to customize the existing system, you can modify the Python scripts.
But, as mentioned, this requires Bash 4.0 or higher.
Maybe something like:
curl https://raw.githubusercontent.com/rcaloras/bash-preexec/master/bash-preexec.sh -o ~/.bash-preexec.sh
echo '[[ -f ~/.bash-preexec.sh ]] && source ~/.bash-preexec.sh' >> ~/.bashrc
then add the following to .bashrc too
preexec() { type "$1" >/dev/null 2>&1 || echo -n 'WTF??? '; }
reload your shell, then try enter some nonexistent command, like bububu
$ bububu
will print
WTF??? -bash: bububu: command not found
Important: read https://github.com/rcaloras/bash-preexec

Bash function not executing the input command

In a bash file s.sh, I have an Executor function to which I pass the commands to be executed. Whenever some command does not work as expected, this function outputs the command.
Executor()
{
if ! $*
then
echo "$*"
exit 2
fi
}
Now I am invoking this function -
Executor clangPath="Hello" make (This is used to set the value of clangPath variable as "Hello" in the makefile)
This caused an error -
./s.sh: line 5: clangPath=Hello: command not found
[./s.sh] Error: clangPath=Hello make
However executing the same command like this works fine
if ! clangPath="Hello" make
then
echo "HelloWorld!"
fi
After looking at the error, I thought there might be a mistake with the string quotations, so I tried
exitIfFail clangPath='"Hello"' make
Even this resulted in an error -
./s.sh: line 5: clangPath="Hello": command not found
[./s.sh] Error: clangPath="Hello" make
What could be the reason for the error?
If the purpose of the function is to execute some Bash expression, then print an error message, if the expression failed (returned non-zero status), then, there is a way to implement this via eval:
#!/bin/bash -
function Executor()
{
eval "$#"
if [ $? -ne 0 ]
then
echo >&2 "Failed to execute command: $#"
exit 2
fi
}
The $? variable holds the exit status of the previously executed command. So we check if it is non-zero.
Also note how we redirect the error message to the standard error descriptor.
Usage:
Executor ls -lh /tmp/unknown-something
ls: cannot access /tmp/unknown-something: No such file or directory
Failed to execute command: ls -lh /tmp/unknown-something
Executor ls -lh /tmp
# some file listing here...
The $# variable is more appropriate here, as eval interprets things itself. See $* and $#.

use of ? in sh script

When I went through some shell scripts I came across the following line of codes
FILENAME=/home/user/test.tar.gz
tar -zxvf $FILENAME
RES=$?FILENAME
if [ $RES -eq 0 ]; then
echo "TAR extract success
fi
I want to know
What is the use of '?' mark in front of the variable(RES=$?FILENAME).
How to check whether tar extracted successfully
In standard (POSIX-ish) shells, $? is a special parameter. Even Bash's parameter expansion doesn't document an alternative meaning.
In the context, $?FILENAME might expand to 0FILENAME if the previous command succeeded, and perhaps 1FILENAME if it failed.
Since there's a numeric comparison requested (-eq) the value 0FILENAME might convert to 0 and then compare OK. However, on my system (Mac OS X 10.10.5, Bash 3.2.57) attempting:
if [ 0FILE -eq 0 ]; then echo equal; fi
yields the error -bash: [: 0FILE: integer expression expected.
So, adding the FILENAME after the $? is unorthodox at best (or confusing, or even, ultimately, wrong).
By default, the exit status of a function is the exit status returned by the last command in the function. After the function executes, you use the standard $? variable to determine the exit status of the function:
#!/bin/bash
# testing the exit status of a function
my_function() {
echo "trying to display a non-existent file"
ls -l no_file
}
echo "calling the function: "
my_function
echo "The exit status is: $?"
$
$ ./test4
testing the function:
trying to display a non-existent file
ls: badfile: No such file or directory
The exit status is: 1
To check if tar successfully executed or not use
tar xvf "$tar" || exit 1

Sourcing a script file in bash before starting an executable

I'm trying to write a bash script that "wraps" whatever the user wants to invoke (and its parameters) sourcing a fixed file just before actually invoking it.
To clarify: I have a "ConfigureMyEnvironment.bash" script that must be sourced before starting certain executables, so I'd like to have a "LaunchInMyEnvironment.bash" script that you can use as in:
LaunchInMyEnvironment <whatever_executable_i_want_to_wrap> arg0 arg1 arg2
I tried the following LaunchInMyEnvironment.bash:
#!/usr/bin/bash
launchee="$#"
if [ -e ConfigureMyEnvironment.bash ];
then source ConfigureMyEnvironment.bash;
fi
exec "$launchee"
where I have to use the "launchee" variable to save the $# var because after executing source, $# becomes empty.
Anyway, this doesn't work and fails as follows:
myhost $ LaunchInMyEnvironment my_executable -h
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: /home/bin/my_executable -h: No such file or directory
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: exec: /home/bin/my_executable -h: cannot execute: No such file or directory
That is, it seems like the "-h" parameter is being seen as part of the executable filename and not as a parameter... But it doesn't really make sense to me.
I tried also to use $* instead of $#, but with no better outcoume.
What I'm doing wrong?
Andrea.
Have you tried to remove double quotes in exec command?
Try this:
#!/usr/bin/bash
typeset -a launchee
launchee=("$#")
if [ -e ConfigureMyEnvironment.bash ];
then source ConfigureMyEnvironment.bash;
fi
exec "${launchee[#]}"
That will use arrays for storing arguments, so it will handle even calls like "space delimited string" and "string with ; inside"
Upd: simple example
test_array() { abc=("$#"); for x in "${abc[#]}"; do echo ">>$x<<"; done; }
test_array "abc def" ghi
should give
>>abc def<<
>>ghi<<
You might want to try this (untested):
#!/usr/bin/bash
launchee="$1"
shift
if [ -e ConfigureMyEnvironment.bash ];
then source ConfigureMyEnvironment.bash;
fi
exec "$launchee" $#
The syntax for exec is exec command [arguments], however becuase you've quoted $launchee, this is treated as a single argument - i.e., the command, rather than a command and it's arguments. Another variation may be to simply do: exec $#
Just execute it normally without exec
#!/usr/bin/bash
launchee="$#"
if [ -e ConfigureMyEnvironment.bash ];
then source ConfigureMyEnvironment.bash;
fi
$launchee
Try dividing your list of argumets:
ALL_ARG="${#}"
Executable="${1}"
Rest_of_Args=${ALL_ARG##$Executable}
And try then:
$Executable $Rest_of_Args
(or exec $Executable $Rest_of_Args)
Debugger

Resources