Variable not interprate inside loop shell script - bash

I tried to made a save inside a SSH connection from files inside a folder with a script, I don't understand why but
expect \"ssh>\"
send \"for ENTRY in "pathtomyfolder"/*; do cp /DOMP/appli/bin/$(basename $ENTRY) /pathtofolder/$(basename $ENTRY).somedate; done \r\"
But it seems that my variable isn't interprate inside my script, it's empty. If I launched the loop from the SSH connection it works fine it's juste inside the script that it doesn't work. If you could help me thank you.
Edit : Thank for you replies sorry for my lack of informations, I've made a minimal reproductible example :
#!/bin/sh
HORODATAGE=`date "+%Y%m%d%H%M%S"`
for entry in "folder"/*
do
cp "\$entry" "\$entry.$HORODATAGE"
done
I've tried to escape my variable but it doesn't work too...

By escaping the variables, you basically told the shell "please do not expand it". Hence, you should have written it as
#!/bin/sh
HORODATAGE=`date "+%Y%m%d%H%M%S"`
for entry in "folder"/*
do
cp "$entry" "$entry.$HORODATAGE"
done
BTW, I would write the assignment of the date as
HORODATAGE=$(date "+%Y%m%d%H%M%S")
but of course, your approach is not wrong either.

Related

How to run a bash script multiple times with same output?

This seems like a weird question to have, but I need to write a simple bash script that takes two arguments from the command line. The script looks like this:
#!/bin/bash
while getopts a:b: flag; do
case "${flag}" in
a) optionA="${OPTARG}";;
b) optionB="${OPTARG}";;
esac
done
echo $optionA
echo $optionB
When I run . script.sh -a optionA -b optionB it works exactly as expected and echos the two inputs. The issue is if I run the exact same script again, the arguments are not echoed and I just see two blank lines. Only the first time running it produces the correct behavior. If I close the terminal session and try again it works, but I'd like to be able to run it several times in a row.
I was thinking the issue had something to do with the variables remaining and then being overwritten by the next run so I tried something like unset optionA, but it did not help.
I apologize if this is a simple question, but I could not seem to find an answer anywhere else and I would much appreciate any help. Thanks!
EDIT: The simple solution is that I was sourcing the script when I could have been running it. Using bash test.sh -a optionA -b optionB works just fine.
EDIT 2: If there is a need to source instead of run, the answer Charles gave also works; use unset OPTIND after each run.
To reset getopts between sourced invocations of your script, unset OPTIND.
This variable tells getopts how many items have already been processed, and thus how many should be skipped.
By contrast, if you just run your script without sourcing it, this variable won't be held over, so there's nothing to reset.

Bash script: referencing a folder path from the script folder, and not from where I run it

I just bumped into a bug in redis install_server script
it has a hardcoded :
DEFAULT_CONFIG="../redis.conf"
so when running this script not from its own folder (such as ./utils/install_server.sh)
the script fails to find the conf file.
I'm looking for a way to reference the scripts folder without a dependency on where the script is called from.
I looked into this answer which seems to be the canonical on SO but something is failing for me:
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo $DIR
and I get:
./utils/install_server.sh: 100: ./utils/install_server.sh: Bad substitution
/home/myusername/binaries/redis-2.8.3 #where I run the script from..not the folder I need
So I guess I'm doing something wrong, or this isn't the correct answer for me
I know I can add a check if the file exists and a clearer error message to the redis install script, but I rather just make this work.
I'll be glad for ideas, and I'll make a PR to redis to fix this for everyone..
Thanks!
I do something very similar to what you have posted:
SCRIPT_DIR="$(cd $(dirname $0) && pwd)"
It seems that in your case, something is wrong with BASH_SOURCE. In my approach, I use $0 which always evaluates to the full pathname used to launch the script.
I'm not sure what the problem with BASH_SOURCE is in your script as what you posted works for me. Thus I am just offering an alternate approach.
Are you running this with bash (i.e. start the script with #!/bin/bash or run it with bash /path/to/script), or plain sh (#!/bin/sh or sh /path/to/script)? Both BASH_SOURCE and arrays ([0]) are bash extensions, and may not be available in a generic shell. In particular, the "Bad substitution" error is one I've seen from trying to use arrays in a shell that doesn't support them.

"Escaping" nightmare

I have been trying to put the following into a bash script:
scp /cygdrive/c/Program\ Files\ \(x86\)/Spiceworks/data/configurations/LA_$(date +%F)-firewall-5520 "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08\ -\ Security/Firewalls"
...which works as expected via command line.
When I try to place it in a script, I'm obviously going to have to double escape the spaces, anything else? I'm unable to have success with the multitude of variations I've tried.
I would think:
scp /cygdrive/c/Program\\ Files\\ \(x86\)/Spiceworks/data/configurations/LA_\$(date\ +%F)-firewall-5520 "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08\\ \\-\\ Security/Firewalls"
...would work, but it doesn't. Any suggestions, before I go grey and bald? Thanks
I wont waste the space with all variations I've tried, but I will say I have tried escaping almost everything and basically nothing and many in between with no success. When I receive a "No such file or Directory" I obviously escape until the file actually resolves, but even when I do not get a path error, the command is not successfully completing.
I do understand this is quite a specific case, but I imagine it will help others in the future: escaping spaces, in a bash script, using embedded expect (I have tested with a #!/bin/bash shebang and the embedded expect using expect -c ' .... ' as well as #!/usr/bin/expect using a simple spawn scp command with no change.
EDIT (Based on responses):
I should have mentioned I have tried quoting it...
Quoting the first (host) part gives me the error
can't read "(date +%F)": no such variable
while executing
"spawn scp "/cygdrive/c/Program Files (x86)/Spiceworks/data/configurations/LA_$(date +%F)-firewall-5520" "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_..."
...it is not a variable, it is a function giving me the current date in the format year-month-day
Quoting the destination section without escaping anything gives me the error
scp: ambiguous target
The same command that worked on your bash shell should work the same in your bash script. You shouldn't and cannot escape it twice.
If it doesn't work, make sure you're testing the script from the same terminal, ensure that the script contents and your command is identical, then paste the output from your terminal when you do:
$ scp /cygdrive/c/Program\ Files\ \(x86\)/Spiceworks/data/configurations/LA_$(date +%F)-firewall-5520 "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08\ -\ Security/Firewalls"
(successful scp output here)
$ cat testscript
(testscript contents here, should be identical to above scp command)
$ bash testscript
(unsuccessful script/scp output here)
Just stick it in quotes and stop hitting yourself, as #that_other_guy said, you cannot, and shouldn't try and escape twice, wherever you got that idea, disregard it as a source of information. (my guess is it came from "thin air")
scp "/cygdrive/c/Program Files (x86)/Spiceworks/data/configurations/LA_$(date +%F)-firewall-5520" "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08 - Security/Firewalls"
You could even give yourself some helpers:
export PROGFILESx86="/cygdrive/c/Program Files (x86)"
export SPICEWORKS_CONFIGS="${PROGFILESx86}/Spiceworks/data/configurations"
(add them to .bashrc, exec it.) and then do:
scp "${SPICEWORKS_CONFIGS}/LA_$(date +%F)-firewall-5520" "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08 - Security/Firewalls"
I'd also be concerned the the files you are attempting to scp actually exist, wrap it up in a condition to verify they're there, it only makes sense when you're auto-generating a filename.
firewall_config="${SPICEWORKS_CONFIGS}/LA_$(date +%F)-firewall-5520"
if [ -e "${firewall_config}" ]
then
scp "${firewall_config}" "sf-mlawler#10.21.1.212:/home/sf-mlawler/SBOX_Automation/SBOX_Dumps/08 - Security/Firewalls"
else
echo "File doesn't exist: ${firewall_config}"
fi
Update:
Since you've updated your question, it's obviously the date call that's giving you the biggest problem, again, indirection saves you doing bizarre escape-char-yoga, just get the result into a var and use that.
fw_date=$(date +%F)
firewall_config="${SPICEWORKS_CONFIGS}/LA_${fw_date}-firewall-5520"

new to bash scripting; trying to figure out why SOURCE command doesn't execute

I have made a really sincere effort to figure this out, and I just can't. This is my very simple bash script. The lines that begin "export" and "echo" seem to work, so I know my script is executing. If I enter the line that begins "source" at the prompt in the terminal I get a lot of printed output that indicates that the command is running, but if I execute my script, nothing happens (and in fact subsequent efforts to use Freesurfer indicate that it hasn't worked). I have a feeling there may be something very basic I don't get about bash scripting, but I can't figure out what that thing is from looking at tutorials.
#!/bin/bash
export FREESURFER_HOME=/foo/freesurfer
echo "starting freesurfer"
echo $FREESURFER_HOME
source $FREESURFER_HOME/SetUpFreeSurfer.sh
export SUBJECTS_DIR=/bar/my_dir
If you run your script using ./scriptname.sh it is exexuted in a subshell. Every variable that is set there etc cannot change the environment of the parent shell. In order to do so you need to source the script.
See eg. this question on superuser

cp in a bash script

I am working on a simple shell script (my first one) and cannot seem to figure out why this is failing when I run ./auto.sh baz. It was working initially when I had hard coded in the full destination path, but now that I want to use an argument it breaks. Any help would be awesome. Thanks!
#!/bin/sh
cp -ivr ./foo/bar.xcodeproj ./iOS/$1.xcodeproj
Try the following
#!/bin/sh
cp -ivr "./foo/bar.xcodeproj" "./iOS/${1}.xcodeproj"

Resources