data.txt But I don't want to store that on disk. Is there a way to define a file in RAM and store it there for a while? Or is htere a way to store it in an environment. Note that the assignment copies the original variable to the new one (assignment by value), so changes to one will not affect the other. This may also have relevance if you need to copy something like a large array inside a tight loop. An exception to the usual assignment by value behaviour within PHP occurs with objects.">
Skip to content

Korn Shell Variable Assignment Php

Ubuntu Forums > The Ubuntu Forum Community > Ubuntu Specialised Support > Development & Programming > Programming Talk > assign the exit status of a command to a variable


PDA

View Full Version : assign the exit status of a command to a variable



foormea

March 1st, 2007, 09:39 PM

hi all
first, i'm sorry for this newbie question. i'm learning bash programming and i'm now somewhat confused... :(

i'm trying to assign the exit status of the following command _directly_ to a variable:

synclient -l | grep TouchpadOff | grep -q 1

i thought that (( ...... )) would work but it doesn't


duff

March 1st, 2007, 10:11 PM

like this?

# $(exit 1)

# echo $?
1

# $(exit 4)

# echo $?
4


foormea

March 1st, 2007, 10:17 PM

thanks for the suggestion but this is not what i'm trying to do :)

i could do:
synclient -l | grep TouchpadOff | grep -q 1
TOUCHPAD_STATUS=$?

but i'm trying to have the exit status of the "synclient -l | grep TouchpadOff | grep -q 1" expression directly assigned to TOUCHPAD_STATUS


duff

March 1st, 2007, 10:54 PM

$? gives you exit status, do you want the program's output?


foormea

March 1st, 2007, 11:28 PM

what i'm trying to get is the exit status without supplying the command on the line before assigning it to the variable. i don't think i'm being exactly clear :D

basically, i'm trying to do something like:
TOUCHPAD_STATUS=exit_status_of_"synclient -l | grep TouchpadOff | grep -q 1"

without using a function

pretty much like variable=`uname -r` would assign the output of uname -r to variable
but what i want is the exit status

OR
if it's impossible to get the exit status this way, it seems that (( ... )) returns 1 if the expression inside returns a non-null result (or something like that). but i can't figure out how that works.


duff

March 1st, 2007, 11:41 PM

are you just trying to avoid the output? how about piping to dev null?

synclient -l | grep TouchpadOff | grep -q 1 &>/dev/null
TOUCHPAD_STATUS=$?


foormea

March 2nd, 2007, 12:05 AM

lol, not trying to avoid the output, grep -q does it :)

trying to get TOUCHPAD_STATUS=............ WITHOUT executing the command before


LotsOfPhil

March 2nd, 2007, 12:54 AM

So duff's 2 line solution is inacceptable?


Mr. C.

March 2nd, 2007, 02:14 AM

If you are using bash, you can use PIPESTATUS:


# echo Hello | (grep goo )
# echo ${PIPESTATUS[0]} ${PIPESTATUS[1]}
0 1

Otherwise, $? is always the exit status of the last command in a pipeline.


s1ightcrazed

March 2nd, 2007, 03:30 AM

To do it on a single line, you can use:

TEST=$(ls -l > /dev/null)$?

Put whatever command you want in the () and the variable will get assigned to the exit status of that command. I do this all the time for compatibility checks (when doing cross platform stuff). You can even do:

if [[ $(synclient -l | grep TouchpadOff | grep -q 1 )$? == 0 ]]; then echo "true"; fi

Basically using the exit status to determine if the system that the command is run on can actually handle the command first. Mind you I don't have to resort to this trick often, but it does come in handy from time to time.

Enjoy!


Mr. C.

March 2nd, 2007, 03:39 AM

That's a good trick s1ightcrazed.

It might be more accurate to say "will get assigned the exit status of the last command" rather than "will get assigned to the exit status of that command".

Very nice.


foormea

March 2nd, 2007, 06:32 PM

s1ightcrazed, this is EXACTLY what i needed. thanks a lot!!!


foormea

March 3rd, 2007, 10:35 PM

got a problem, i really can't understand...

(synclient -l returns the total list of options of the touchpad. i wanna know if the touchpad is on or off)

this works fine, first executing the set of commands then reading $?


#!/bin/sh
synclient -l | grep TouchpadOff | grep -q 1
case "$?" in
0 )
echo "off";;
1 )
echo "on";;
esac
exit 0


however i'd like to assign the exit status directly. i know it's useless since the previous script works fine, but still... :)

typing this directly at the shell prompt works fine:


echo `synclient -l | grep TouchpadOff | grep -q 1`$?

returning 0 when it's off, and 1 when on

but why the hell won't this script work???:


#!/bin/sh
case "`synclient -l | grep TouchpadOff | grep -q 1`$?" in
0 )
echo "off";;
1 )
echo "on";;
esac
exit 0

in order to try to understand why it doesn't work, i also tried doing:


test=`synclient -l | grep TouchpadOff | grep -q 1`$?
echo $test

works perfectly at command prompt
but doesn't work in a script........................................... :((((( :((((((((


Mr. C.

March 3rd, 2007, 10:53 PM

Too many new programmers want to jump in without reading and learning from the documentation. Let me suggest when things aren't working, you try to digest the sometimes challenging documentation. From man bash, the syntax of a case statement is:

case word in [ [(] pattern [ | pattern ] ... ) list ;; ] ... esac

So, what is a "word". Again, man bash tells us:

word A sequence of characters considered as a single unit by the
shell. Also known as a token.

So, can you now see why your attempt doesn't work?

MrC


foormea

March 3rd, 2007, 11:45 PM

hey Mr. C.
i appreciate your help and i promise i'll rely more on doc from now on :)

word: A token that is not an operator.

token: A sequence of characters considered a single unit by the shell. It is either a word or an operator.

operator: A control operator or a redirection operator. See section 3.6 Redirections, for a list of redirection operators.

control operator: A word that performs a control function. It is a newline or one of the following: `||', `&&', `&', `;', `;;', `|', `(', or `)'.

----> my command uses the | operator and therefore can't work in a case construct.
ok, understood and thanks for telling me to check the doc :)

however, i still can't understand why

test=`synclient -l | grep TouchpadOff | grep -q 1`$?
echo $test
works, but why

#!/bin/sh
test=`synclient -l | grep TouchpadOff | grep -q 1`$?
echo $test
won't work.

-------------> okay just found out that /bin/sh is a symlink to /bin/dash. it works fine when using #!/bin/bash instead of #!/bin/sh. i'll read doc about what dash is

okay, thanks master Mr. C. !


po0f

March 3rd, 2007, 11:50 PM

foormea,

Dash is a gimped Bash, change it:


$ sudo dpkg-reconfigure dash

Answer "No".


Mr. C.

March 3rd, 2007, 11:55 PM

Yes, I was just replying when I saw the other posters comment too.

Always know what interpreter (#! line at the top of your scripts) you are using.

sh != bash != ksh
csh != tcsh

MrC


foormea

March 3rd, 2007, 11:58 PM

mmhhhh, since it's said that dash is faster than bash, shouldn't i keep dash as default /bin/sh shell, and just use #!/bin/bash instead of #!/bin/sh in my scripts?


Mr. C.

March 4th, 2007, 12:01 AM

You should NOT reconfigure /bin/sh unless you are certain of the ramifications. The shell is critical to early boot up - mess with this inappropriately, and you won't boot.

There is nothing your system does with the shell that is time critical in this manner.


po0f

March 4th, 2007, 12:04 AM

Mr. C.,

I've been using Bash as the default shell interpreter since Dapper and have yet to see any side effect, besides my scripts automatically being run through Bash instead of Dash.


foormea

March 4th, 2007, 12:06 AM

ok :)
thanks guys for your help!


Mr. C.

March 4th, 2007, 12:17 AM

Mr. C.,

I've been using Bash as the default shell interpreter since Dapper and have yet to see any side effect, besides my scripts automatically being run through Bash instead of Dash.

I didn't say it can't or shouldn't be done; I said to be sure to understand.

If something goes terribly wrong with someone's system who took up your advice, are you going to go over and fix it for that person? :-)

MrC


po0f

March 4th, 2007, 12:22 AM

Mr. C.,

I have given this advice on several occasions, and AFAIK the results have only been positive.

Now, if something were to go wrong because of any advice I had given, I would certainly go out of my to help the user repair the situation. I don't do house calls though. ;)


Mr. C.

March 4th, 2007, 12:30 AM

This reminds of a guy named Timothy Treadwell. For over a dozen years he believed in his position. I don't think he's a believer anymore.


Powered by vBulletin® Version 4.2.2 Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.

I'm working on learning some bash scripting skills, primarily how to deal with command line parameters, and I came across a problem. I'm trying to put my usage statement in a variable, and then just echo that variable on a failure. However, it always echos to a single line. Here's my test script:

Code:

#!/bin/bash

read -d '' USAGE <<_EOF_
usage: -option1=value1 ... -optionX=valueX
options:
   -i=*    --interface=*        Specifies interface value, eg -i=eth0
   -n=*    --name=*             Specifics name, eg -n=ep1
_EOF_
ERR_USAGE=1

INTERFACE=
NAME=

for i in $*
do
        case $i in
        -i=* | --interface=*)
                INTERFACE=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
                ;;
        -n=* | --name=*)
                NAME=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
                ;;
        *)
                echo $USAGE >&2
                exit $ERR_USAGE
                ;;
        esac
done

echo "INTERFACE=$INTERFACE"
echo "NAME=$NAME"

exit 0



If I run it with invalid syntax, it prints the usage message, but as so:

Code:

[user@host ~]$ ./testparms.sh fubar
usage: -option1=value1 ... -optionX=valueX options: -i=* --interface=* Specifies interface value, eg -i=eth0 -n=* --name=* Specifics name, eg -n=ep1
[user@host ~]$



I've tried using cat to form the variable, I also just tried having it be defined across multiple lines, i.e.

Code:

USAGE="usage: -option1=value1 ... -optionX=valueX
options:
   -i=*    --interface=*        Specifies interface value, eg -i=eth0
   -n=*    --name=*             Specifics name, eg -n=ep1"



But to no avail. I'm sure this is some nuance of linux strings that I'm just overlooking. Any help is appreciated. Also any comments about how I'm handling parameters is also appreciated. I know there's a camp that likes getopts, but I thought this was fairly creative as well.