LinuxQuestions.org
Visit the LQ Articles and Editorials section
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 01-24-2009, 09:35 AM   #1
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Rep: Reputation: 16
bash - setting a persistent variable that remains after the script exits


Hello to the group...

I've got a Sony Vaio VGN NR-160E (Sony M/N PCG-7Z1L) laptop. I recently discovered through searches that I can control the backlight with a little program called "xbacklight". However, it requires that on first run a program called "xrandr" is run. This is no big deal. Just write a short, simple little diddy that runs xrandr first, then xbacklight with the first command-line variable as the brightness. No big deal.


The problem is that xrandr blanks the screen momentarily. It's quite distracting, though harmless as far as I can tell. Since xrandr is only required to have been run once at any time since boot before the brightness is set, and it stays resident so it's not needed again, I want only to run xrandr the very first time this script is run from reboot.

I could make entries for startup scripts, but I'd like to make a script that I can upload and say "get these two programs and run this script" regardless of distro, and I can't do that if I have to say "oh, and you need to make this change to your startup scripts". I want it easy for the other people. (I'm doing this as a tiny little way to start giving back to the FOSS community, though I realize it's not much.)


So, I have this script pretty much written, except for one tiny little thing. I can't tell if xrandr has already run or not.

My question then is this:

How can I set a variable in a shell script that will persist in the environment outside of the script so that if the script completes and is run again later the variable is still present in the new execution?

I can set the var with no problem and check it and everything else within the script, but say I have pseudocode something like this:

Code:
Begin-------------------
Check if variable exists.  Does it?
--Yes
----Echo "Variable exists...  moving on..."
----Call "set-backlight"
--No
----Set variable to some value (arbitrary)
----Echo "xrandr hasn't run yet;  running xrandr..."
----Run xrandr
----Call "set-backlight"

set-backlight()
{
  Echo "Setting backlight brightness as requested..."
  Run xbacklight with appropriate arguments
  return
}

End---------------------
It's the "check if variable exists" option that gets me.

Now, I've found some references in one of the usenet groups by a couple of gents named "Bit Twister" and "Chris F. A. Johnson" (though I don't remember which newsgroup it was) that referenced a bunch of ways of testing variables in bash, and they all work, except that if I exit the script and come back to it, the variables no longer exist. I've tested this with

Code:
Begin-------------------

Check if variable exists
--Yes
----Echo "Variable exists"
----Exit
--No
----Echo "Variable Does not exist.  Setting now."
----Set variable to whatever

Check if variable exists
--Yes
----Echo "Variable was successfully set"
----Exit
--No (never runs)
----Echo "Variable was NOT set..."

End---------------------
and gotten predictable and expected results.

I just want to set the variable in one script, and either in a second running of that same script or even from another script be able to see that same variable with the same setting.


Any help, please?

Last edited by CJ Chitwood; 01-24-2009 at 09:36 AM. Reason: Second paragraph - why only running xrandr once is necessary
 
Old 01-24-2009, 10:59 AM   #2
bgeddy
Senior Member
 
Registered: Sep 2006
Location: Liverpool - England
Distribution: slackware64 13.37 and -current, Dragonfly BSD
Posts: 1,810

Rep: Reputation: 227Reputation: 227Reputation: 227
Well - as the script runs it own instance of bash variables are lost when the script exits variables are lost. You could "source" a script so it's commands are ran in the user's bash session or have a disk based flag file to indicate the run status. Another option is to have a self modifying bash script. I have written a litte example here:
Code:
#!/bin/bash
if [  -n "$1"  ];then
       if  [ "$1" = "-F" ]; then
		if [ "$(tail -n1 $0)" = "#END" ]; then
			echo "Clearing END indicator"
			sed -i '$d' $0
			exit 0
		else
			echo "Error - no end indicator to clear"
			exit 1
		fi
	else
		echo "Useage $0 [-F] .. -F forces the prior run indicator to be cleared"
		exit 1
	fi
fi
if [ "$(tail -n1 $0)" = "#END" ];then
	echo "We've been ran before"
else
	echo "First time run"
	echo "#END" >> $0
fi
exit 0
You could incorporate this system into your script. It checks to see if it's been ran before by looking for a flag "#END" as the last line. If it's not there it adds it and does some stuff. This may be cleared by running the script with "-F" parameter. You could clear this flag on shutdown with rc.shutdown or such like and run the script on startup from rc.local or some such way.
 
Old 01-24-2009, 11:06 AM   #3
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Original Poster
Rep: Reputation: 16
Thank you.

I'm trying to avoid having to put anything in the startup/shutdown scripts, but it's looking more like I'll have to write some kind of C code or something to accomplish that. Startup/shutdown edits may be the only easy way to do it...


I was thinking about it some more, though... If xbacklight only works after xrandr is set, what does xrandr set in the system that makes xbacklight work? Why not just look for that item and if it doesn't exist, then run xrandr? That would work... I just have to find out what xrandr does so I know what to look for... :shrugs:

Thanks, and I'll keep your suggestion in mind.
 
Old 01-24-2009, 11:31 AM   #4
pcunix
Member
 
Registered: Dec 2004
Location: MA
Distribution: Various
Posts: 149

Rep: Reputation: 23
Quote:
Originally Posted by CJ Chitwood View Post
Thank you.

I'm trying to avoid having to put anything in the startup/shutdown scripts, but it's looking more like I'll have to write some kind of C code or something to accomplish that. Startup/shutdown edits may be the only easy way to do it...

An "ls -lut" of xandr will tell you when something last used it.. you could compare that you your login time from "last" and run it again if needed.
 
Old 01-24-2009, 11:49 AM   #5
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,151

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
From your description, xrandr sounds like a X rendering "add-on" which may be running as a separate process. Try a ps -e | grep xrandr to see if there's a process by that name running. If there is, then all you need in your script is

[ -z "$(ps -e | grep xrandr)" ] && xrandr

to start it if it's not running.

(I'd check myself, but I'm stuck on Vista right now. I've started a big download that I don't want to interrupt.)
 
Old 01-24-2009, 01:59 PM   #6
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by pcunix View Post
An "ls -lut" of xandr will tell you when something last used it.. you could compare that you your login time from "last" and run it again if needed.
Good idea -- this is quite acceptable. Instead of login time, though, I'm thinking of using the time "gdm" or some similarly used-every-login program is run because it would be easier to directly compare times (really, not much different, since with "last" I'd simply have to add a grep for "still" (still logged in), but at least comparing the output of "ls" to "ls" will use the same "cut" command as opposed to comparing "ls" to "last").

The only problem then would be with logging in before midnight and running the program both before and after midnight, but this is an extremely unlikely scenario and running xrandr a second time per login really isn't anything major.

I'm going to run with this and see what I can get... Thanks!


Still open to other suggestions though!
 
Old 01-24-2009, 02:01 PM   #7
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by PTrenholme View Post
From your description, xrandr sounds like a X rendering "add-on" which may be running as a separate process. Try a ps -e | grep xrandr to see if there's a process by that name running. If there is, then all you need in your script is

[ -z "$(ps -e | grep xrandr)" ] && xrandr

to start it if it's not running.

(I'd check myself, but I'm stuck on Vista right now. I've started a big download that I don't want to interrupt.)
Hmm... Well, this still runs xrandr every time... I must have been wrong -- the xrandr is not running resident, so I don't know what it's doing that allows xbacklight to work only after it has run. Whatever it is, when I find it, I'll have a guaranteed "will it work" qualifier....

I will strace it sometime tonight when I get back to the computers to see if it's writing to a file or something...

Thanks though... All else fails, I'll run with the time-stamp idea above...
 
Old 01-24-2009, 06:31 PM   #8
PTrenholme
Senior Member
 
Registered: Dec 2004
Location: Olympia, WA, USA
Distribution: Fedora, (K)Ubuntu
Posts: 4,151

Rep: Reputation: 331Reputation: 331Reputation: 331Reputation: 331
Well, I finished the download, and -- now back on Fedora -- I looked at man xrandr and discovered that it was just a interface to RandR, not a daemon that would keep running. If it's called with no arguments, all it does is report the current rendering state of screen :0
Code:
$ xrandr
Screen 0: minimum 320 x 240, current 1440 x 900, maximum 1440 x 900
default connected 1440x900+0+0 0mm x 0mm
   1440x900       50.0*
   1024x768       51.0
   800x600        52.0     53.0
   640x512        54.0
   640x480        55.0     56.0
   512x384        57.0
   400x300        58.0
   320x240        59.0
This implies to me that when you said
Quote:
However, it requires that on first run a program called "xrandr" is run.
in your first post, you neglected to mention the arguments used when you invoked the program.

In any case, look at man xrandr to see how you can use the command to report the current state of whatever setting you were changing in the first call, and write your script so it only changes the setting when it doesn't have the desired value.
 
Old 01-24-2009, 06:40 PM   #9
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Original Poster
Rep: Reputation: 16
yes, that's what I was thinking at 3:00 when I posted last... Xrandr is setting something, somewhere, so all I need to do is find it. However, the strace I just ran was less than helpful (maybe I just don't know enough about strace yet).

So, I think now I'll read up on XRandR and get info on what exactly it's changing... or you're right, I should just check the output of xrandr by itself and see what is changed!

And sorry, I didn't realize I would need the arguments to xrandr in the post, but I see they may have helped much earlier on...

Thanks!
 
Old 01-24-2009, 07:48 PM   #10
CJ Chitwood
Member
 
Registered: Dec 2006
Location: Jacksonville, FL
Distribution: Mint. Regrettably.
Posts: 127

Original Poster
Rep: Reputation: 16
GOT IT! Thanks to all for the help!

I run debian, and the following are installed. I really don't think I need the -dev package installed, but I list it just in case...

libxrandr2
libxrandr-dev
xbacklight


There should be similar packages available for other distros.


My script is as follows


Code:
#!/bin/bash
# by CJ Chitwood
# cj.chitwood <from> gmail.com
# with the help of linuxquestions.org 
#
# http://www.linuxquestions.org/questions/programming-9/bash-setting-a-persistent-variable-that-remains-after-the-script-exits-699591/ 
# (and Google hits too numerous during my searches to remember) 
#
# This file is not maintained.  It is provided as-is and 
# may be considered free-use/public domain.
#
# requires programs "xrandr" and "xbacklight".  Edit PATH to 
# point to the directories that contain these.  In Debian, this 
# is /usr/bin.
##############################################################################

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin; export PATH

if [ $# -ne 1 ]; then
    echo -e 1>&2 Usage: setbl [arg], where 0 \<\= [arg] \<\= 100.
    exit 127
  else
    ARG=$1;
fi

setBacklight()
{ echo Attempting to set backlight to $ARG%...
  xbacklight -set $ARG
  return
}


TEMPVAR=`xrandr --verbose | grep BACKLIGHT_CONTROL | cut -d : -f 2 | cut -d " " -f 2`

if [ $TEMPVAR == "native" ]; then
    setBacklight
    exit 0
  elif [ $TEMPVAR == "kernel" ]; then
    echo xrandr has not yet been run.  Running xrandr...
    xrandr --output LVDS --set BACKLIGHT_CONTROL native
    setBacklight
  else 
    # This block of code should, in theory, never run; 
    # but, since I only own a VGN-NR160E, I can't test other 
    # models to be sure of this assumption.
    echo xrandr shows an unknown backlight control state...
    echo The current output of "xrandr --verbose | grep BACKLIGHT_CONTROL" is:
    echo     $TEMPVAR
    echo and since I expect either "native" or "kernel", I don\'t know what 
    echo to do with it...
    echo I wonder if you\'re running me on a Sony Vaio VGN NR-series...
    echo Not continuing, since state is unknown.  Try manual controls...  
fi

exit 0

Last edited by CJ Chitwood; 01-25-2009 at 10:13 PM. Reason: Code alignment cleanup, remove @ sign from e-mail address.
 
  


Reply

Tags
backlight, bash, brightness, control, debian, laptop, persistent, script, shell, sony, vaio, variable, xrandr


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
passing variable from bash to perl in a bash script quadmore Programming 6 02-21-2011 04:11 AM
Log what exits in bash script. What causes exit code thats not 0? Trailsmoke Programming 2 09-25-2008 03:07 AM
Bash Script Help - Trying to create a variable inside script when run. webaccounts Linux - Newbie 1 06-09-2008 02:40 PM
setting a variable variable in a script... this works, but could it be more elegant? pwc101 Programming 3 08-18-2006 11:23 AM
Flagging exits in Bash Script dtheorem Programming 5 11-08-2003 10:15 PM


All times are GMT -5. The time now is 02:46 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration