External Variables not being recognized correctly - bash

i have got this problem: When i put my variables into an external "configstyle" file and import the file with . /var/scripts/siDiagConfig.sh the variables don´t work properly...
Like i have a variable called MTU=1500 and when i echo it, it prints "1500", which is correct. But when I want to use the variable within a grep command like somethingawesome | grep ${MTU} -c the variable is not recognized properly. In this example, the console prints 0, instead of 2... When i reassign the variable with MTU=1500, the code works without any problems....
Any idea, what i could have missed?
Is there any other way, i could put my variables in an external file?
my siDiagConfig.sh File:
#!/bin/bash
....
export MTU=1500
....
edit (Solution):
I remembered, that i created the file on my windows system. I just copied the code in the siDiagConfig.sh, created a new file on the unix system, and pasted the code there. Now it works without any problems =)
Thanks for the help!

[gigauser#gigabox : /scm/gigafolder/toratora/test_aks]
cat conf.config ; echo -----; cat testfile.txt ; echo ------; cat mainfile.sh ; echo --------; ./mainfile.sh
export GIGA=giga
export fifa=FIFA
I'm GIGA
I like fifa
#!/bin/bash
. conf.config
echo GIGA = $GIGA
echo fifa = $fifa
cat -n testfile.txt
echo
echo -- Now lets grep = $GIGA with case insensitive On
echo
echo -`grep -in "${GIGA}" testfile.txt`-;
echo =`grep -ic "${GIGA}" testfile.txt`=
echo
echo Now again but with case insensitive Off
echo -`grep -n "${GIGA}" testfile.txt`-;
echo =`grep -c "${GIGA}" testfile.txt`=
GIGA = giga
fifa = FIFA
1 I'm GIGA
2 I like fifa
-- Now lets grep = giga with case insensitive On
-1:I'm GIGA-
=1=
Now again but with case insensitive Off
--
=0=
[gigauser#gigabox : /scm/gigafolder/toratora/test_aks]
>

Since feature requests to mark a comment as an answer remain declined, I copy the above solution here.
Yes; that \r is the trouble. It is a carriage return. Convert DOS files to Unix files before executing them on Unix. – Jonathan Leffler
Ok, now i remembered, that i created the file on my windows system. I just copied the code in the siDiagConfig.sh, created a new file on the unix system, and pasted the code there. Not it works without any poroblems =) Thanks for the help! – Simons0n

Related

Bash Script IF statement not functioning

I am currently testing a simple dictionary attack using bash scripts. I have encoded my password "Snake" with sha256sum by simply typing the following command:
echo -n Snake | sha256sum
This produced the following:
aaa73ac7721342eac5212f15feb2d5f7631e28222d8b79ffa835def1b81ff620 *-
I then copy pasted the hashed string into the program, but the script is not doing what is intended to do. The script is (Note that I have created a test dictionary text file which only contains 6 lines):
echo "Enter:"
read value
cat dict.txt | while read line1
do
atax=$(echo -n "$line1" | sha256sum)
if [[ "$atax" == "$value" ]];
then
echo "Cracked: $line1"
exit 1
fi
echo "Trying: $line1"
done
Result:
Trying: Dog
Trying: Cat
Trying: Rabbit
Trying: Hamster
Trying: Goldfish
Trying: Snake
The code should display "Cracked: Snake" and terminate, when it compares the hashed string with the word "Snake". Where am I going wrong?
EDIT: The bug was indeed the DOS lines in my textfile. I made a unix file and the checksums matched. Thanks everyone.
One problem is that, as pakistanprogrammerclub points out, you're never initializing name (as opposed to line1).
Another problem is that sha256sum does not just print out the checksum, but also *- (meaning "I read the file from standard input in binary mode").
I'm not sure if there's a clean way to get just the checksum — probably there is, but I can't find it — but you can at least write something like this:
atax=$(echo -n "$name" | sha256sum | sed 's/ .*//')
(using sed to strip off everything from the space onwards).
couple issues - the variable name is not set anywhere - do you mean value? Also better form to use redirection instead of cat
while read ...; do ... done <dict.txt
Variables set by a while loop in a pipeline are not available in the parent shell not the other way around as I mistakenly said before - it's not an issue here though
Could be a cut n paste error - add an echo after the first read
echo "value \"$value\""
also after atax is set
echo "line1 \"$line1\" atax \"$atax\""

Use first 3 characters of a filename as a variable in shell script

this is my first post so hopefully I will make my question clear.
I am new to shell scripts and my task with this one is to add a new value to every line of a csv file. The value that needs added is based on the first 3 digits of the filename.
I bit of background. The csv files I am receiving are eventually being loaded into partitioned oracle tables. The start of the file name (e.g. BATTESTFILE.txt) contains the partitioned site so I need to write a script that takes the first 3 characters of the filename (in this example BAT) and add this to the end of each line of the file.
The closest I have got so far is when I stripped the code to the bare basics of what I need to do:
build_files()
{
OLDFILE=${filename[#]}.txt
NEWFILE=${filename[#]}.NEW.txt
ABSOLUTE='path/scripts/'
FULLOLD=$ABSOLUTE$OLDFILE
FULLNEW=$ABSOLUTE$NEWFILE
sed -e s/$/",${j}"/ "${FULLOLD}" > "${FULLNEW}"
}
set -A site 'BAT'
set -A filename 'BATTESTFILE'
for j in ${site[#]}; do
for i in ${filename[#]}; do
build_files ${j}
done
done
Here I have set up an array site as there will be 6 'sites' and this will make it easy to add additionals sits to the code as the files come through to me. The same is to be siad for the filename array.
This codes works, but it isn't as automated as I need. One of my most recent attempts has been below:
build_files()
{
OLDFILE=${filename[#]}.txt
NEWFILE=${filename[#]}.NEW.txt
ABSOLUTE='/app/dss/dsssis/sis/scripts/'
FULLOLD=$ABSOLUTE$OLDFILE
FULLNEW=$ABSOLUTE$NEWFILE
sed -e s/$/",${j}"/ "${FULLOLD}" > "${FULLNEW}"
}
set -A site 'BAT'
set -A filename 'BATTESTFILE'
for j in ${site[#]}; do
for i in ${filename[#]}; do
trust=echo "$filename" | cut -c1-3
echo "$trust"
if ["$trust" = 'BAT']; then
${j} = 'BAT'
fi
build_files ${j}
done
done
I found the code trust=echo "$filename" | cut -c1-3 through another question on StackOverflow as I was researching, but it doesn't seem to work for me. I added in the echo to test what trust was holding, but it was empty.
I am getting 2 errors back:
Line 17 - BATTESTFILE: not found
Line 19 - test: ] missing
Sorry for the long winded questions. Hopefully It contains helpful info and shows the steps I have taken. Any questions, comment away. Any help or guidance is very much appreciated. Thanks.
When you are new with shells, try avoiding arrays.
In an if statement use spaces before and after the [ and ] characters.
Get used to surrounding your shell variables with {} like ${trust}
I do not know how you fill your array, when the array is hardcoded, try te replace with
SITE=file1
SITE="${SITE} file2"
And you must tell unix you want to have the rightside eveluated with $(..) (better than backtics):
trust=$(echo "${filename}" | cut -c1-3)
Some guidelines and syntax help can be found at Google
Just use shell parameter expansion:
$ var=abcdefg
$ echo "${var:0:3}"
abc
Assuming you're using a reasonably capable shell like bash or ksh, for example
Just in case it is useful for anyone else now or in the future, I got my code to work as desired by using the below. Thanks Walter A below for his answer to my main problem of getting the first 3 characters from the filename and using them as a variable.
This gave me the desired output of taking the first 3 characters of the filename, and adding them to the end of each line in my csv file.
## Get the current Directory and file name, create a new file name
build_files()
{
OLDFILE=${i}.txt
NEWFILE=${i}.NEW.txt
ABSOLUTE='/app/dss/dsssis/sis/scripts/'
FULLOLD=$ABSOLUTE$OLDFILE
FULLNEW=$ABSOLUTE$NEWFILE
## Take the 3 characters from the filename and
## add them onto the end of each line in the csv file.
sed -e s/$/";${j}"/ "${FULLOLD}" > "${FULLNEW}"
}
## Loop to take the first 3 characters from the file names held in
## an array to be added into the new file above
set -A filename 'BATTESTFILE'
for i in ${filename[#]}; do
trust=$(echo "${i}" | cut -c1-3)
echo "${trust}"
j="${trust}"
echo "${i} ${j}"
build_files ${i} ${j}
done
Hope this is useful for someone else.

Sed append to end of line directory

I'm very new to SED and I'm having a hard time trying to append to an end of a directory. What I'm doing involves 2 basic things with sed but for some reason, no changes are made after the script runs. I will show segments of my script
I have a bash script that pulls my home directory from the host and I define the ID variable.
USERNAME="test"
#pull the home directory
dir=$(ssh -n -t $SERVERNAME "echo \$HOME";)
the above example will store /export/home/ID in the dir variable
echo $dir | sed 's/\([/export/home]*\).*/\1/' > olddir
the sed command above stores /export/home/ in the file olddir (takes off the ending)
sed -i 's_/home/$ _\$USERNAME_' olddir
i am now trying to change /export/home/ to /export/home/test using the defined variable with the escaped $.
after the script runs, it still has /export/home/ as the entry in the olddir file.
I'm using the -i to modify the file and I think I'm using the deliminators correctly? what could I be doing wrong? i even took off the $ from the USERNAME variable which didn't do anything. I know I'm missing something small but i just can't figure it out. I really appreciate your time to answer my question.
I think your command line can be modified then redirect output to olddir as follows:
echo $dir | sed 's#\(/export/home\).*#\1#' > olddir
to add the USERNAME VARIABLE
sed -i "s#/export/home#&/$USERNAME#" olddir
After using the provided information and playing around with the code, I found a solution that will work for both /export/home/ID and /home/ID situations.
I used both Xorg and also gniourf_gniourf's suggestions and below is my result.
echo $dir | sed 's_\([/export/home\]*\).*_\1_' > olddir
The above code is the first part of my solution.
I used what Xorg provided for the above code but it looks like i need those [] so i can use the *\ if i have it as echo $dir | sed 's_\(/export/home\).*_\1_' > olddir then the olddir file will contain /export/home/ID/test after the following sed command is used.
Here is the following sed command that I used:
sed -i 's_/home_&/'"$USERNAME"'_' olddir
The above code is the second part of my solution. I figured that I really only need to put focus on /home/ since i'm appending after it. I looked at gniourf_gniourf's comment and used the example where the quotes to isolate $USERNAME with "" that seems to be the way you can tell the script to use $USERNAME as a variable and not just put in the characters $USERNAME.
so after the script is run, depending on the host, I either have export/home/test/ or /home/test/ I can now put either of these into a new variable on the script to use to specify the home directory when creating ID's on remote hosts!
newdir="$(cat olddir)"
Thank you all so much for your help. I wouldn't have been able to figure this out with out your help.
Update: it turns out that the traling / at the end of directory is problem so i found a much easier way to replace the ID in the home directory
newdir="${dir/ID/${USERNAME}}"
i used these if statments for both home directory situations
`if [[ $dir == "/home/dhabinsk" ]]; then
newdir="${dir/dhabinsk/${USERNAME}}"
fi
if [[ $dir == "/export/home/dhabinsk" ]]; then
newdir="${dir/dhabinsk/${USERNAME}}"
fi`
cheers

Using variables in bash script to set ini-file values while executing

I am quite new to bash scripting, but haven't found an answer to the following problem yet. I hope somebody can either tell me or give me tips on how to do it.
Background: I have a program (say "program") that accepts an ini-file (say "input.ini") as input taking a while to execute. A variable in the ini-file for the programm might be "number" for instance, which might be set to number=1.
Problem: I have to call ./program input.ini quite often, but with different values for "number", say 1,2,3,4,5.
I thought, I could write a bash script executing the program in a for-loop setting "number" accordingly. The loop is not a problem, but setting "number" in the ini-file. (I tried e.g. number=$VALUE in the ini-file with VALUE being set in the script, but this does not work.)
Question: How can I set a variable in the ini-file using a bash-script? (This does not have to be permanent, but only for that run of the program.)
Additional question: Setting a variable in the ini-file is one thing. In addition, it would be great to do the following as well (I thought that might work similarly...): The program produces some output files. The names of these files can also be set in the ini-file, say via "output_name=filename.out". It would be great now if there was something like "output_name=filename_$VALUE.out" to set the output names accordingly.
I hope it is clear what I try to do and I would be really grateful if somebody had a solution or hints on how to do it.
Thanks,
Cari
If you have a file that contains number=something, you can replace "something" with "5" using sed "/^number=/s/=.*/=5/.
This is something you can do once off with process substituion:
./program <(sed "/^number=/s/=.*/=5/" baseinput.ini)
Or you can create a new ini file based on the old one, as in
sed "/^number=/s/=.*/=5/" baseinput.ini > input.ini
./program input.ini
You could also define the entire ini file the script, and substitute in a here document:
N=5
./program - << EOF
[Section]
number=$N
foo=bar
EOF
full parsed and set ini file (section,key,value) and save on root.
sudo_setini ()
{
fkey=false
fsec=false
tsec=false
res=""
if [ -f "$1" ]; then
while IFS= read -r LINE
do
TLINE=`echo $LINE`
if [[ $TLINE == \[*] ]]; then
TLINE=`echo ${TLINE:1:${#TLINE}-2}`
if [[ _${TLINE} == _$2 ]]; then
tsec=true
fsec=true
else
if $tsec && ! $fkey ; then
res+=$'\n'$3=$4
fi
tsec=false
fi
res+=$'\n'${LINE}
else
TLINE=`echo ${TLINE%%=*}`
if $tsec && [[ _${TLINE} == _$3 ]]; then
fkey=true
res+=$'\n'${LINE%%=*}=$4
else
res+=$'\n'${LINE}
fi
fi
done < $1
fi
if $tsec && ! $fkey ; then
res+=$'\n'$3=$4
fi
if ! $fsec ; then
res+=$'\n'[$2]
res+=$'\n'$3=$4
fi
echo "$res" | sudo tee "$1" > /dev/null
}
sudo_setini 'test.ini' 'General' 'Type' 'Digital_'
Not quite sure whether this helps or not:
This calls the program script five times:
for n in 1 2 3 4 5
do
./program $n input.ini
done
Then in program, refer to the first parameter $n as $1.
The second parameter input.ini is $2.
If you have git available and you're not worried about indentation, a hack could be to use git config.
Example:
$ git config -f settings.ini server.ip 123.123.123.123
$ cat settings.ini
[server]
ip = 123.123.123.123
$ git config -f settings.ini server.ip 123.123.123.124
$ cat settings.ini
[server]
ip = 123.123.123.124

unix shell: check file list in dir versus with list of files from a file

I am trying to write a sh script to check check that all files from list of files' extentions stored in a file are in a place in a particular dir. I am doing following:
file names looks like yyyymmdd.ext
hoff_list.lst sample is following:
abc
dfg
hij
klm
xxx
...
my script is:
#!/bin/ksh
PATH=$PATH:/usr/bin
_input="/exchange/hoff_list.lst"
hoffdate="20130328"
hsourcedir="/upload_data/"
while IFS=' \t\n' read -r line; do
echo "=$line=" #first problem there
hoff_name=$hsourcedir$hoffdate"."$line
if test ! "$hoff_name"
then echo "$hoff_name DOES exist"
else echo "$hoff_name does NOT exist or is empty"
fi
done < "$_input"
but it doesnt revert relevant reply. It doesnt find a file if the file is reqly exists in dir.
echo "=$line="
reterns
=abc
=dfg
...
when expected
=abc=
=dfg=
...
looks problem is there, but haven't a clue how to handle it. Will appreciate your help there...
The file /exchange/hoff_list.lst has CRLF line endings http://en.wikipedia.org/wiki/Newline.
Get rid of CR. You can try using the dos2unix utility available on most Linux systems or refer to http://en.wikipedia.org/wiki/Newline#Conversion_utilities.

Resources