How to get variables config from shell [closed] - linux

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
Improve this question
cat a.sh
#!/bin/bash
t=1232
echo $1
#echo $t
when i run the script "./a.sh $t" I can't get value 1232
when the script replacement with echo $t ,run the script "./a.sh" can get vaule 1232
can anybody else tell me ,if i use "./a.sh $t" this form ,how can get the vaule,thanks alot
have no ideas to get the variables throug the termi

When you run "./a.sh $t your current shell evaluates $t to '' so $1 is unset in your script and it will just execute echo.
If you quote the the variable either ./a.sh \$t or ./a.sh '$t' your script will do echo '$t'. You can then use either eval to get it to evaluate the expression:
eval echo "$1"
or preferable strip off the leading '$' and use indirect variable:
var=${1:1}
echo "${!var}"
If you just need to store data use json or sqlite instead of a script.
If you have logic in your script consider just passing in the variable names and if not set dump all variables (using the name convention that your variables are lower case):
#!/bin/bash
if [ -z "$1" ]
then
set | grep "^[a-z]"
exit 0
fi
for v in "$#"
do
set | grep "^$v="
done
and you then do:
$ ./a t
t=1232
$ ./a
t=1232

I think your variable t are out of scope. Therefore, what you want to do is assign the variable t=1232, beforehand, and use it as an argument. So the script would be
#!/bin/bash
echo $1
Then call the script as you wanted to with variable t already assigned to the value, so it would print the desired output
t=1232
./script.sh $t
I think that's that. would love to hear your thoughts tho

Related

Converting content of files to uppercase [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
So I have a shell script called "concat" that currently takes command line arguments and prints the contents of files named on the command line. I need to now create a script called "concatconvert" that calls the "concat" script, takes the contents of files and converts them.
The following is the code of my script "concat":
#!/bin/bash
if [ $# -eq 0 ]; then
printf "Usage: concat FILE ... \nDescription: Concatenates FILE(s)
to standard output separating them with divider -----.\n" >&2
exit 1
fi
for var in "$#"
do
if [[ ! -e "$var" ]]; then
printf "One or more files does not exist\n" >$2
exit 1
fi
done
for var in "$#"
do
if [ -f "$var" ]; then
cat $var
printf -- "-----\n"
fi
done
exit 0
I am going to be calling "concat" using
#!/bin/bash
./concat
in the concatconvert script.
Concatconvert is going to take arguments "-u" and "-l"
Ultimately the script would be executed as:
./concatconvert -u test1.txt test2.txt
-u converts contents of files to uppercase.
For example, "This is a test" becomes "THIS IS A TEST".
-l converts contents of files to lowercase.
For example, "This is a test" becomes "this is a test".
Only one option can be provided at a time.
I am not too sure where to begin on this. I appreciate any help.
You should use tr command as mentioned by #jenesaisquoi.
The tr command in UNIX is a command-line utility for translating or
deleting characters.
To use it to change everything to lower case command would be :
echo "This is Test" | tr [:upper:] [:lower:]
this is test
To use it to change everything to upper case command would be :
echo "This is Test" | tr [:lower:] [:upper:]
THIS IS TEST
To use it for a file use below command :
tr '[:upper:]' '[:lower:]' < filename

How to write a "bash script.sh argument " [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
hi can someone help me with this.
How to Write a script that takes in as argument a filename and displays its modification date and time in this way exactly :
[user#localhost...]$ bash script.sh temp.txt
the file temp.txt was modified on May 1 20:20
And then modify that script in such a way that it lists the modification dates for directories whose names contain a given pattern in this way exactly :
[user#local....]$ bash script.sh testRegex Pub
the file testRegex was modified on May 1 20:22
the directory /home/user/Public was modified on Dec 26 08:00
the directory /home/user/Pubs. was modified on May 2 20:00
please help I need to answer this fast
Thanks
This is pretty simple to do actually. You should read up on the stat command as #John Bollinger said. I also used the date command to format the date. You can read up on taking arguments for a script here
Combining all of this would give -
#!/bin/bash
filename=$1;
dirname=$2;
file_mod_date=`date -d #$( stat -c %Y $1 ) +%m" "%B" "%H:%M`;
echo "The file ${filename} was modified on ${file_mod_date}";
if [ "$2" == "" ]; then
exit 1;
else
for i in /home/user/*${dirname}*/; do
dir_mod_date=`date -d #$( stat -c %Y $i ) +%m" "%B" "%H:%M`;
echo "The directory ${i} was modified on ${dir_mod_date}";
done
fi
A good way to do this is with passing options and values:
For example:
file_name=""
help_message="To use this script type script.sh --file /path/to/file.txt"
# -- Get input options (if any)
while [[ $# > 0 ]] ;do
key="$1"
case ${key,,} in
-f|--file)
file_name="${2,,}"
shift
;;
-h|--help)
echo -e "$help_message"
exit;
shift
;;
esac
shift
done
Call the script like this:
bash script.sh -f "temp.txt"
With regard to the "logic" of the script, you will have to figure that out ;-)

I would like to understand this shell script [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
This is an assignment I received.
I have been requested to explain what the purpose of this code is. However, when I execute this, there does not appear any output.
As I am new to shell scripting, could somebody help me out?
Thanks a lot.
#!/bin/bash
# $1 = node IP
# $2 = node port
# $3 = hostname to resolve
[[ $# != 3 ]] && logger -p local0.error -t ${0##*/} -- "usage: ${0##*/} <node IP> <node port> <hostname to resolve>" && exit 1
node_ip=$(echo $1 | sed 's/::ffff://')
dig +short #$node_ip $3 IN A &> /dev/null
[[ $? == 0 ]] && echo “UP”
$#: number of parameters passed to your script, if you execute this script like this: bash filename.sh p1 p2 p3 p4, the $# in the filename.sh will be evaluated to 4
$?: return value of the previous command. In shell, return value of non-zero means something wrong happened.
[[ $# != 3 ]] && logger ... && 1: means if the amount of parameters is not 3, then log something and exit with return value 1
node_ip=$(echo $1 | sed 's/::ffff://'): replace the ::ffff: in the first parameter and assign it to node_ip
dig +short #$node_ip $3 IN A &> /dev/null: call dig command and redirect the output to /dev/null, so you can't see any thing printed out. By the way, I don't know what dig does
[[ $? == 0 ]] && echo “UP”: if dig command (namely the previous command) returns a zero value, which means SUCCESS, then print the word UP

How to compare variables in for loop bash [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I want to create if statement, but in this statement are some errors
for i in ${#:2} ; do
if (( $2 -eq $i ))
then
continue
fi
done
How to fix my if statement
Your statement only works for integers.
If you want to compare them as strings, you can use [[ "string1" = "string2" ]]:
$ cat -v myscript
#!/bin/bash
for i in "${#:2}" ; do
if [[ "$2" = "$i" ]]
then
echo "$2 and $i are the same"
else
echo "$2 and $i are different"
fi
done
$ chmod +x myscript
$ ./myscript dummy target foo bar target
target and target are the same
target and foo are different
target and bar are different
target and target are the same
As you can see from this runnable example, it works. If you find that it doesn't on your system, you should provide a complete example like the above demonstrating it.
I would suggest
if [ "$2" = "$i" ]

How to properly handle wildcard expansion in a bash shell script?

#!/bin/bash
hello()
{
SRC=$1
DEST=$2
for IP in `cat /opt/ankit/configs/machine.configs` ; do
echo $SRC | grep '*' > /dev/null
if test `echo $?` -eq 0 ; then
for STAR in $SRC ; do
echo -en "$IP"
echo -en "\n\t ARG1=$STAR ARG2=$2\n\n"
done
else
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
fi
done
}
hello $1 $2
The above is the shell script which I provide source (SRC) & desitnation (DEST) path. It worked fine when I did not put in a SRC path with wild card ''. When I run this shell script and give ''.pdf or '*'as follows:
root#ankit1:~/as_prac# ./test.sh /home/dev/Examples/*.pdf /ankit_test/as
I get the following output:
192.168.1.6
ARG1=/home/dev/Examples/case_Contact.pdf ARG2=/home/dev/Examples/case_howard_county_library.pdf
The DEST is /ankit_test/as but DEST also get manupulated due to '*'. The expected answer is
ARG1=/home/dev/Examples/case_Contact.pdf ARG2=/ankit_test/as
So, if you understand what I am trying to do, please help me out to solve this BUG.
I'll be grateful to you.
Thanks in advance!!!
I need to know exactly how I use '*.pdf' in my program one by one without disturbing DEST.
Your script needs more work.
Even after escaping the wildcard, you won't get your expected answer. You will get:
ARG1=/home/dev/Examples/*.pdf ARG2=/ankit__test/as
Try the following instead:
for IP in `cat /opt/ankit/configs/machine.configs`
do
for i in $SRC
do
echo -en "$IP"
echo -en "\n\t ARG1=$i ARG2=$DEST\n\n"
done
done
Run it like this:
root#ankit1:~/as_prac# ./test.sh "/home/dev/Examples/*.pdf" /ankit__test/as
The shell will expand wildcards unless you escape them, so for example if you have
$ ls
one.pdf two.pdf three.pdf
and run your script as
./test.sh *.pdf /ankit__test/as
it will be the same as
./test.sh one.pdf two.pdf three.pdf /ankit__test/as
which is not what you expect. Doing
./test.sh \*.pdf /ankit__test/as
should work.
If you can, change the order of the parameters passed to your shell script as follows:
./test.sh /ankit_test/as /home/dev/Examples/*.pdf
That would make your life a lot easier since the variable part moves to the end of the line. Then, the following script will do what you want:
#!/bin/bash
hello()
{
SRC=$1
DEST=$2
for IP in `cat /opt/ankit/configs/machine.configs` ; do
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
done
}
arg2=$1
shift
while [[ "$1" != "" ]] ; do
hello $1 $arg2
shift
done
You are also missing a final "done" to close your outer for loop.
OK, this appears to do what you want:
#!/bin/bash
hello() {
SRC=$1
DEST=$2
while read IP ; do
for FILE in $SRC; do
echo -e "$IP"
echo -e "\tARG1=$FILE ARG2=$DEST\n"
done
done < /tmp/machine.configs
}
hello "$1" $2
You still need to escape any wildcard characters when you invoke the script
The double quotes are necessary when you invoke the hello function, otherwise the mere fact of evaluating $1 causes the wildcard to be expanded, but we don't want that to happen until $SRC is assigned in the function
Here's what I came up with:
#!/bin/bash
hello()
{
# DEST will contain the last argument
eval DEST=\$$#
while [ $1 != $DEST ]; do
SRC=$1
for IP in `cat /opt/ankit/configs/machine.configs`; do
echo -en "$IP"
echo -en "\n\t ARG1=$SRC ARG2=$DEST\n\n"
done
shift || break
done
}
hello $*
Instead of passing only two parameters to the hello() function, we'll pass in all the arguments that the script got.
Inside the hello() function, we first assign the final argument to the DEST var. Then we loop through all of the arguments, assigning each one to SRC, and run whatever commands we want using the SRC and DEST arguments. Note that you may want to put quotation marks around $SRC and $DEST in case they contain spaces. We stop looping when SRC is the same as DEST because that means we've hit the final argument (the destination).
For multiple input files using a wildcard such as *.txt, I found this to work perfectly, no escaping required. It should work just like a native bash app like "ls" or "rm." This was not documented just about anywhere so since I spent a better part of 3 days trying to figure it out I decided I should post it for future readers.
Directory contains the following files (output of ls)
file1.txt file2.txt file3.txt
Run script like
$ ./script.sh *.txt
Or even like
$ ./script.sh file{1..3}.txt
The script
#!/bin/bash
# store default IFS, we need to temporarily change this
sfi=$IFS
#set IFS to $'\n\' - new line
IFS=$'\n'
if [[ -z $# ]]
then
echo "Error: Missing required argument"
echo
exit 1
fi
# Put the file glob into an array
file=("$#")
# Now loop through them
for (( i=0 ; i < ${#file[*]} ; i++ ));
do
if [ -w ${file[$i]} ]; then
echo ${file[$i]} " writable"
else
echo ${file[$i]} " NOT writable"
fi
done
# Reset IFS to its default value
IFS=$sfi
The output
file1.txt writable
file2.txt writable
file3.txt writable
The key was switching the IFS (Internal Field Separator) temporarily. You have to be sure to store this before switching and then switch it back when you are done with it as demonstrated above.
Now you have a list of expanded files (with spaces escaped) in the file[] array which you can then loop through. I like this solution the best, easiest to program for and easiest for the users.
There's no need to spawn a shell to look at the $? variable, you can evaluate it directly.
It should just be:
if [ $? -eq 0 ]; then
You're running
./test.sh /home/dev/Examples/*.pdf /ankit_test/as
and your interactive shell is expanding the wildcard before the script gets it. You just need to quote the first argument when you launch it, as in
./test.sh "/home/dev/Examples/*.pdf" /ankit_test/as
and then, in your script, quote "$SRC" anywhere where you literally want the things with wildcards (ie, when you do echo $SRC, instead use echo "$SRC") and leave it unquoted when you want the wildcards expanded. Basically, always put quotes around things which might contain shell metacharacters unless you want the metacharacters interpreted. :)

Resources