I am writing a simple bash script (I am fairly new to bash). I am trying to assign the output of a command to a variable and I can't seem to get it to work properly. See below:
#!/bin/bash
HOST=`hostname`
MEMORY=`prtconf -v |grep Memory |awk '{print $3}'`
echo "os_instance_name "$HOST
echo "physical_machine_ram "$MEMORY
I am able to get the result of hostname properly but my MEMORY variable is not being populated with the output from the command.
Some ideas spring to my mind:
execute the script in debug mode
$ bash -x myscript.sh
Put the variable expansions within the double quotes
echo "os_instance_name $HOST"
echo "physical_machine_ram $MEMORY"
Try this:
memory=`free -m | grep Mem | awk '{print $2}'`
echo $memory
should return the physical memory in megabytes
Also, $1 in the code that you have provided might be referring to a blank column. Try using $2.
Related
Given the variables listed below:
echo ${userupper}_PYTHON
# YTU_PYTHON
echo $YTU_PYTHON
# /home/ytu/anaconda3/bin/python
echo $path
# foo.py
Now I'd like to execute /home/ytu/anaconda3/bin/python foo.py with userupper and path. I tried $(${userupper}_PYTHON) $path but it ends up with error messages including:
YTU_PYTHON: not found
foo.py: not found
It seems like it takes $(${userupper}_PYTHON) as bare YTU_PYTHON rather than expected $YTU_PYTHON. How should I do to make it right?
Edits:
The suggested duplication should have solved my problem. However for some unknown reasons it's not working.
#!/usr/bin/env bash
for user in ytu
do
. /home/${user}/.profile
userupper=$(echo ${user} | awk '{print toupper($0)}')
userpython=${userupper}_PYTHON
cd /home/${user}/H2-ML/crons
for path in $(ls | grep ^${user}_.*_monthly_report.py$)
do
echo ${userpython}
echo $path
echo $YTU_PYTHON
echo ${!userpython}
done
done
The code chunk above returns:
YTU_PYTHON
ytu_clinic249_monthly_report.py
/home/ytu/anaconda3/bin/python
send_monthly_reports.sh: 14: send_monthly_reports.sh: Bad substitution
, which makes me so confused.
Try this:
command=${userupper}_PYTHON
echo ${!command} $path # ommit echo if you want to execute command
in your case it echos:
/home/ytu/anaconda3/bin/python foo.py
Here is link that might be useful if you want to write bash scripts. You should not parse ls output in the nutshell.
You also create unnecessary new process, both lines do the same:
$(echo ${user} | awk '{print toupper($0)}')
${user^^} #paramenter expansion
See also my previous question.
So... I have a script:
function go_loop (){
for i in `grep -v ^# $1`; do
$2
done
}
go_loop "/tmp/text.txt" "echo $i"
I should have in a result:
9
20
21
...
But apparently I only get an empty result. How can I feed the second input parameter to the loop?
Please don't advice me do this:
for i in `grep -v ^# $1`; do
echo $i
done
I need to make 2 input parameters, first - name of file, second - name of execution command
You need to eval the second parameter like this:
eval $2
and pass it like this:
go_loop "/tmp/text.txt" 'echo $i'
You can do this using exec inside your loop, which will run the $2 as bash command:
[root#box ~]# ./test.sh 1 ls
test.sh tests_passed.txt
[root#box ~]# cat test
exec $2
The exec builtin command is used to
replace the shell with a given program (executing it, not as new process)
set redirections for the program to execute or for the current shell
I have done a simple shell script:
#!/bin/sh
file_name=$1
state=`cat "$file_name" | grep "port protocol" | awk '{print $4}'`
echo $state
reason=`cat "$file_name" | grep "port protocol"`
echo $reason
This outputs the values $state and $reason.
However, when I run..
echo $state
..in the console it does not output nothing. It seems like the variable loses its value. Is this the normal behaviour or should I had something to the script?
Thanks!
Assuming that you're running your script like ./script.sh or sh script.sh, then this is the expected behaviour. Child processes cannot change the environment of their parent. The fact that you're running a shell script from a shell doesn't change this rule.
What you can do is source the script instead of executing it, to set those variables in the local environment:
. script.sh
This effectively runs the lines of the script in your current shell, so the variables will be set there.
While I've got your attention, I'd recommend making the following changes to your script:
#!/bin/sh
file_name=$1
state=$(awk '/port protocol/ {print $4}' "$file_name")
echo "$state"
reason=$(grep "port protocol" "$file_name")
echo "$reason"
In short, quote your variables, avoid useless calls to cat and use pattern matching in awk rather than piping grep to it.
Doing a simple script in work and I can't figure out why it will not output the results in another file.
/tmp/system stores the node list
#!/bin/bash
$results=restest.txt
for i in $(cat /tmp/system); do
ping -c 1 $i
if [ $i = 0 ]; then
ssh $i ps -ef | grep ops | echo > $results
fi
done
echo is not printing from stdin but rather its arguments (or a newline if there no arguments). So
echo file.txt
only prints 'file.txt', not the content of the file. Therefore your code only writes a newline to the file. You can use cat for printing stdin to stdout, but here it is useless, since you can pipe the grep output directly to the file:
ssh $i ps -ef | grep ops > $results
first thank you for editing your code (it's more clear like this :)
I have 2 or 3 advices :
1- when you want to store a value in variable dont use "$" symbole, this symbole is used to get the variable's value
ex:
MYVAR=3
echo MYVAR "this will print MYVAR"
echo $MYVAR "this will print 3"
2- always quote your values, specially if the value is comming from another command
3- To fix your script you need to quote the command executed on the remote machine,
then redirect the output to your file
ex:
ssh user#MachineA "ls > file.txt" "file.txt is created on machineA"
ssh user#machineA "ls" > file.txt "file.txt is created on YOUR machine"
so simply you can replace your last line by
ssh $i "ps -ef | grep ops" > $results
try to use -ne in your test bash classictest
good luck
There are several errors. First, don't iterate over files like this. Second, i is the name of the host, not the exit status of ping. Third, the echo is unnecessary (and does not read from standard input). Lastly, $ is only used for expanding a parameter, not assigning to it.
#!/bin/bash
results=restest.txt
while read -r host; do
if ping -c 1 "$host"; then
ssh "$host" ps -ef | grep ops > "$results"
fi
done < /tmp/system
I am trying to use the following pattern inside a shell script eg. I want to use the following:
grep ^"#" $fn | grep -v NM$ > $op
but inside bash script. The problem is normally bash considers everything after the "#" as a comment. If i use
grep ^"\#" $fn
I think it changes the meaning. I am a newbie.
Any help will be appreciated.
There are multiple possibilities:
grep '^#' $fn
or
grep "^#" $fn
or
grep ^\# $fn
Here is a little example which I saved as foo.sh
echo "#"
echo '#' # this is a comment
echo '\#'
when run as sh foo.sh this is what is printed out
#
#
\#