I have written following bash script:
#!/bin/sh
echo "Number of command line arguments : $#"
if [ $# == 0 ]; then
echo "Your command line contains no arguments"
declare -a arr=("xx.xx.xx.xx" "yy.yy.yy.yy")
else
declare -a arr=($1)
fi
for i in "${arr[#]}"
do
URL="https://"$i":8443"
echo "URL is $URL"
wget --no-check-certificate $URL/heapdump
done
It keeps failing with line 16: wget: command not found
I have found some related posts but could not figure out how to fix this. Thanks.
If you type a command (which is is not an internal command or a shell function), bash searches the directories mentioned in the variable PATH for a file of this name (wget in your case), which has the executable bit set for the user running the script. In your case, no suitable wget has been found.
Since it is unlikely that you do have a wget in your PATH without x-bit set, the most likely cause is that the PATH is lacking the directory where your wget lives.
You have two options: Extend the PATH, or explicitly prefix the wget line in your script with the correct path, i.e.
/here/is/my/wget --no-check-certificate $URL/heapdump
For getting path of executable files such as wget please use ‘which’ cmd:
which wget
Output:
/full/path/wget
Related
echo "Enter path of backup file e.g /tmp/backup/etc.tar.gz : "
read PATH #input was /tmp/backup/etc.tar.gz
echo "Enter directory: "
read DIR #input was /root/testing
sudo tar -zvxf "$PATH" -C "$DIR"
when I ran the script, it said that the command was not found. I tried using whatever kind of brackets for the variables but still not working. Any help?
However when I ran the command tar -zvxf /tmp/backup/etc.tar.gz -C /root/testing , it worked.
You're saving something into PATH which is what the shell will search to find the executables. So when you use that variable the shell can't find, say, tar because it is no longer in your search path. Use a different variable name.
I am using Cygwin Terminal to run shell to execute shell scripts of my Windows 7 system.
I am creating directory , but it is getting created with a dot in name.
test.sh
#!/bin/bash
echo "Hello World"
temp=$(date '+%d%m%Y')
dirName="Test_$temp"
dirPath=/cygdrive/c/MyFolder/"$dirName"
echo "$dirName"
echo "$dirPath"
mkdir -m 777 $dirPath
on executing sh test.sh its creating folder as Test_26062015 while expectation is Test_26062015.Why are these 3 special charterers coming , how can I correct it
Double quote the $dirPath in the last command and add -p to ignore mkdir failures when the directory already exists: mkdir -m 777 -p "$dirPath". Besides this, take care when combining variables and strings: dirName="Test_${temp}" looks better than dirName="Test_$temp".
Also, use this for static analysis of your scripts.
UPDATE: By analyzing the debug output of sh -x, the issue appeared due to DOS-style line-endings in the OP's script. Converting the file to UNIX format solved the problem.
The following code checks if you have root authority, then runs the script again with it :
CMDLN_ARGS="$#" # Command line arguments for this script (if any)
export CMDLN_ARGS
func_check_for_sudo() {
if [ ! $( id -u ) -eq 0 ]; then
echo "You may be asked for your login password for [`whoami`]." ;sleep 1
LAUNCH="`dirname \"${0}\"`"
exec sudo -S su -c ${LAUNCH}/$(basename ${0}) ${CMDLN_ARGS}
exit ${?}
fi
}
Where things are going wrong is when I place this script in a "$HOME/bin" folder or something so I can just launch it without the path. It gives me the error "No such file or directory". I need the script to get that information and correctly pass it to exec.
My question is this: how do I get the /path/to/script_name from within a script correctly when it is called without the path? To recap, I'm calling MY_SCRIPT insead /path/to/MY_SCRIPT which breaks my script because it has to check for root authority and run again if you don't have it.
Basically the line of code in question is this where ${0} is the script name (with path if you called it with one):
exec sudo -S su -c ${0} ${CMDLN_ARGS}
There are a couple of problems here:
Finding the path to the script. There are a couple of easy ways to do this: use "$BASH_SOURCE" instead of $0; or simply take advantage of the fact that (at least by default), sudo preserves $PATH, so sudo "$0" ... will resolve the script fine.
The second is that the script doesn't preserve its arguments properly. Spaces within arguments will be mistaken for breaks between arguments, and wildcards will be erroneously expanded. This is because CMDLN_ARGS="$#" mushes all the arguments together separated by spaces, and then ${CMDLN_ARGS} re-splits on spaces (maybe not the same way) and also expands wildcards.
Here's my take at correcting the problems. Note that putting the handler in a function just adds a layer of unnecessary complication, so I just put it inline. I also used sudo's -p option to clean up the prompting slightly.
if [ $( id -u ) -ne 0 ]; then
exec sudo -p "Login password for %p: " "$0" "$#"
exit $?
fi
I am attempting to write a bash script that changes directory and then runs an existing script in the new working directory.
This is what I have so far:
#!/bin/bash
cd /path/to/a/folder
./scriptname
scriptname is an executable file that exists in /path/to/a/folder - and (needless to say), I do have permission to run that script.
However, when I run this mind numbingly simple script (above), I get the response:
scriptname: No such file or directory
What am I missing?! the commands work as expected when entered at the CLI, so I am at a loss to explain the error message. How do I fix this?
Looking at your script makes me think that the script you want to launch a script which is locate in the initial directory. Since you change you directory before executing it won't work.
I suggest the following modified script:
#!/bin/bash
SCRIPT_DIR=$PWD
cd /path/to/a/folder
$SCRIPT_DIR/scriptname
cd /path/to/a/folder
pwd
ls
./scriptname
which'll show you what it thinks it's doing.
I usually have something like this in my useful script directory:
#!/bin/bash
# Provide usage information if not arguments were supplied
if [[ "$#" -le 0 ]]; then
echo "Usage: $0 <executable> [<argument>...]" >&2
exit 1
fi
# Get the executable by removing the last slash and anything before it
X="${1##*/}"
# Get the directory by removing the executable name
D="${1%$X}"
# Check if the directory exists
if [[ -d "$D" ]]; then
# If it does, cd into it
cd "$D"
else
if [[ "$D" ]]; then
# Complain if a directory was specified, but does not exist
echo "Directory '$D' does not exist" >&2
exit 1
fi
fi
# Check if the executable is, well, executable
if [[ -x "$X" ]]; then
# Run the executable in its directory with the supplied arguments
exec ./"$X" "${#:2}"
else
# Complain if the executable is not a valid
echo "Executable '$X' does not exist in '$D'" >&2
exit 1
fi
Usage:
$ cdexec
Usage: /home/archon/bin/cdexec <executable> [<argument>...]
$ cdexec /bin/ls ls
ls
$ cdexec /bin/xxx/ls ls
Directory '/bin/xxx/' does not exist
$ cdexec /ls ls
Executable 'ls' does not exist in '/'
One source of such error messages under those conditions is a broken symlink.
However, you say the script works when run from the command line. I would also check to see whether the directory is a symlink that's doing something other than what you expect.
Does it work if you call it in your script with the full path instead of using cd?
#!/bin/bash
/path/to/a/folder/scriptname
What about when called that way from the command line?
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