LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices

Reply
 
Search this Thread
Old 11-08-2005, 08:36 PM   #1
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
Mysterious bash behavior in scripts


Hi All.

Lately I'm experiencing some weird bash behavior. For example, in a script I cannot export variables to the environment, nor do any string comparisons work, such as -z, -n, or just [ "$VAR" = "xyz" ]. For example, the tests of [ -z "$PS1" ] or [ -n "$PS1" ] always fail. And I know PS1 exists because I can see my customized prompt right in front of me and from the SET command as well. I can perform these operations manually, directly from the command line, but not in scripts. Another example is I try grepping some text from a ps ax output into a variable, and then echoing the variable, but the variable will be empty. But perform the same operation from the command line and the variable echoes just fine.

Initially I thought I had lost the sym link to /bin/sh, but I checked that and the link is there. I thought that because in one desperate move I changed a script header from /bin/sh to /bin/bash and then the script magically worked. But I think I was misled by that instance because the exports simply do not work nor do string comparisons.

There might be additional problems, but these are the only ones I have noticed.

Scripts seem to work otherwise. And scripts seem to be working fine as long as I don't try exporting variables or attempt string comparisons. I think---but do not quote me---that the problem is related to running scripts interactively or directly from the command line. I say that only because my system boots just like always and I have noticed no problems with all of my rc.d scripts or those called from within rc.local. The problem seems to occur once I am logged on.

I looked at permissions but root experiences the same problem. I tried an strace and I did not see anything unusual (but I'm no systems expert and the clue could have stared me in the face).

I have been doing a lot of system tweaking lately (just part of my Slackware learning curve ) and possibly I have tweaked something the wrong way. On the other hand, I haven't really been trying to improve by bash skills until very recently, so this problem could have existed for a long time and I never would have noticed until recently.

I really am at a loss as to where to begin troubleshooting. Any help or guidance is much appreciated.
 
Old 11-08-2005, 08:50 PM   #2
egag
Senior Member
 
Registered: Jul 2004
Location: Netherlands
Distribution: Slackware
Posts: 2,721

Rep: Reputation: 52
can you post some ( strangely non working) code between "" tags.
so it's understandable and it can be cut&pasted

egag
 
Old 11-08-2005, 09:33 PM   #3
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Original Poster
Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
Quote:
can you post some ( strangely non working) code...
Sure! The following are test scripts I wrote last night after I convinced myself that something was goofy (which could very well include my conceptual understanding of bash syntax!).

Code:
#! /bin/sh
#initialize variables
export TEST1="text1"
export TEST2="text2"
if [ -n "$TEST1" ] ; then
	echo "TEST1=$TEST1"
fi
if [ -n "$TEST2" ] ; then
	echo "TEST2=$TEST2"
fi
The script will not export the variables. The echo commands work fine within the script but are misleading because the variables will not export. If I manually execute each individual line from the command line the command succeeds and the variables TEST1 and TEST2 are then listed when I execute the set command. But not when executed from within the script.

The export command seems to work elsewhere, as in /etc/profile, for example.

Code:
#! /bin/bash
echo "PS1=$PS1"
echo "PS2=$PS2"
echo "PS4=$PS4"
if [ -z $PS1 ] ; then
 echo non-interactive shell
else
 echo interactive shell
fi
When I run this script from the command line, the script will display variables PS2 and PS4 but not PS1. The script always returns non-interactive shell. Yet I am looking directly at a customized prompt and the PS1 variable is listed when I run set.

Code:
#! /bin/bash

#initialize variables
PROXOMITRON="/mnt/nt_d/Proxomitron/Proxomitron.exe"
. . .
. . .
# Start the Proxomitron filter proxy
echo "Starting the Proxomitron filter proxy."
# is the Proxomitron already running?
if [ "`ps ax | grep -i proxomitron`" = "" ] ; then
	wine $PROXOMITRON & #2>/dev/null &
	while [ "`ps ax | grep -i proxomitron`" = "" ] ; do
		sleep 1 #wait for Proxomitron to load
	done
	echo "Proxomitron started."
else
	echo "The Proxomitron is already running!"
fi
. . .
. . .
This chunk always fails. I can manually launch Proxomitron and then from the command line manually ps ax | grep -i proxomitron and I will return text. But not from within the script. Within the script the command always returns zip.

Code:
if [ -z "$PS1" ] ; then # this script is being run in non-interactive mode
. . .
fi
I have a script in my $HOME/.kde/Autostart directory. When the script is launched at KDE startup, this is non-interactive mode and the [ -z "$PS1" ] test should return true and not execute the subsequent code. But the code executes exactly the same as when I run the script manually from the command line.

I hope these examples help. I'm stumped!
 
Old 11-08-2005, 10:24 PM   #4
gbonvehi
Senior Member
 
Registered: Jun 2004
Location: Argentina (SR, LP)
Distribution: Slackware
Posts: 3,145

Rep: Reputation: 51
That's because when you run a script, it creates it's own "enviroment" and run there. To make a script execute in your current "enviroment" use the source command or . (dot). Like:
Code:
source script.sh
or
Code:
. script.sh
 
Old 11-09-2005, 01:25 AM   #5
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,766

Rep: Reputation: 474Reputation: 474Reputation: 474Reputation: 474Reputation: 474
Also, when you invoke a script with /bin/sh, bash will use the rules for 'sh'. To get the full bash syntax the script should be invoked with /bin/bash.
 
Old 11-09-2005, 07:47 PM   #6
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Original Poster
Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
I'm beginning to think that perhaps some of the problems listed above are conceptual.

Quote:
That's because when you run a script, it creates it's own "environment" and run there. To make a script execute in your current "environment" use the source command or . (dot).
Today I was reading the Advanced Bash Scripting (ABS) Guide. I learned that one cannot use the export command to place a variable into a parent environment. That is, when I include in a script the command export VAR="123", the export command affects only the environment and child processes of the script, and not the parent environment from which the script was launched. This means I cannot manually run a script from the command line and within that script expect the export command to place a new variable into the current environment of the shell in which I launched the script. Thus, in my first example above, the script is functioning properly, despite my initial expectations otherwise. At least now I know that this confusion over the export command is conceptual on my part (Doctor, my arm hurts when I do this. Don't do that anymore!).

I understand the basics of sourcing, but how do I "export" variables that affect the current environment? A script launched manually from the command line is a child process. How do I create variables affecting the current shell? Or better yet, to create permanent global environment variables from a script?

Quote:
Also, when you invoke a script with /bin/sh, bash will use the rules for 'sh'. To get the full bash syntax the script should be invoked with /bin/bash.
I don't understand the full impact of that statement because I don't possess a handy reference source that itemizes the differences and subtleties, but I am appreciating the effects, as witnessed lately. The (ABS) Guide provides a clue that some string manipulations in bash are affected differently, but provides no specifics which string manipulations are different with the extended functions. I do know that I will revise my scripts to use the /bin/bash shebang and not /bin/sh.

Based upon my recent confusion, I can say that certain string comparisons fail when run with a shebang of /bin/sh. Interesting in some respects, but frustrating to no end to those who do not understand there is a difference. I know this now through trial and error and I'm surfing in the hopes of learning more specifics.

Some questions:

1. For scripts that are launched automatically and not from the command line, such as those scripts that are stored in one's $HOME/.kde/Autostart directory, are those scripts considered interactive or non-interactive? I would have thought non-interactive, but inserting some temporary echo statements into my script showed that the PS1 environment variable was set. I thought PS1 was disabled in non-interactive scripts and the presence of PS1 indicates that the script is considered interactive. If so, how do I overcome that? I was trying to use the PS1 variable as a test to determine the output I wanted. I want certain text messages in the script to display to screen when the script is launched manually from the command line, and to output to a log file when run in the background from the Autostart directory. Any ideas?

2. Is a space after the shebang exclamation mark important? I've seen scripts with a space and without.

3. Do the bash startup files (/etc/profile, /etc/bashrc, ~/.bash_profile, ~/.bashrc, ~/.bash_login, ~/.bash_logout) need to be declared as scripts with a shebang? Seems they are all sourced so I would think not. But if not required, does shebanging them anyway modify operations in any way?

4. Do the bash startup files need to be executable? Again, as they are sourced I would think not---and they are not on my box and seem to work fine.
 
Old 11-10-2005, 02:48 AM   #7
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,766

Rep: Reputation: 474Reputation: 474Reputation: 474Reputation: 474Reputation: 474
Sourced files don't need to have a shebang and shouldn't be executable either. Shebangs should have no spaces.

bash has a few features that are not available in sh and has a few syntax differences as well (I don't know which) -hence the difference in behaviour depending on how the script is called.
Try doubling your [] brackets or using the 'test' command directly. I still don't understand fully all the different variable-expansion syntaxes and behaviours -depending on the use of double [], {}, and single/double quote marks, inside parentheses.

rc files are usually Runtime Configuration files which are not normally executable but are read by programs when they start.
 
Old 11-10-2005, 01:23 PM   #8
chesss
LQ Newbie
 
Registered: Nov 2005
Posts: 10

Rep: Reputation: 0
Hey does proxo work well in linux?? Please share the working script, since i miss it dearly in my ubuntu.
Thanks
 
Old 11-10-2005, 05:54 PM   #9
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Original Poster
Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
Quote:
Sourced files don't need to have a shebang and shouldn't be executable either. Shebangs should have no spaces.
Good enough for me! Will update files (and habits) accordingly.

Quote:
bash has a few features that are not available in sh...
That has become obvious to me. Through all the frustration the past few days caused partially by my ignorance of bash, I have nonetheless gotten most of my scripts working just fine. However, string comparisons still seem funky to me and one script does not always execute as I expect because of the string comparison.

Quote:
Hey does proxo work well in linux?
Proxo works just fine under WINE, but my one problematic script I described above is the one that launches Proxo. Here is the code snippet I use:

Code:
...
PROXOMITRON="/mnt/nt_d/Proxomitron/Proxomitron.exe"
WINETEXT="/usr/bin/wine-preloader /usr/bin/wine-kthread"
...
# Start the Proxomitron filter proxy
echo "Starting the Proxomitron filter proxy."
# is the Proxomitron already running?
if [ "`ps ax | grep $WINETEXT $PROXOMITRON`" = "" ] ; then
	echo "   Trying to start Proxomitron..."
	wine $PROXOMITRON 2>/dev/null & # ignore error messages or the script will hang
	sleep 5
	while [ "`ps ax | grep $PROXOMITRON`" = "" ] ; do
		echo "Proxomitron is not loaded."
		sleep 2
	done
	echo "   Proxomitron has started."
else
	echo "The Proxomitron is already running!"
fi
echo "Your browser now should function properly."
...
What has frustrated me is the string comparison I use to determine whether Proxo is already running. Works fine if Proxo is not running, but if I manually launch Proxo (for testing the script), the script reports that Proxo is not running and launches Proxo again. Fortunately WINE works okay in this case and only one instance of Proxo remains running. However, I'd appreciate help how I can write a more robust check to determine whether Proxo is running.

As you can see by my script, I have not installed Proxo locally, but I launch from my NT side.

In a side note, I wish somebody would port this utility to native Linux code. Or possibly provide an equivalent Firefox extension. I am never going to be a css expert and Proxo provides an easier way to filter sites. There is huge potential with this utility and 'nix folks do not realize what they are missing. Most of the original features that made Proxo a hit are now incorporated into most browsers, but there still are some things Proxo does. For example, I use two browsers, Firefox and Opera. FF provides the UA-switcher extension, but nothing like that exists for Opera. So Proxo fills that void. Proxo also allows me to disable various meta tags too. I'm sure these kinds of tweaks are doable in css, but I don't have time for that. What is needed is a user css front-end the works like Proxo.

Now that Opera is available for free, I am interested in switching. There is only one caveat that prevents me: Opera provides no way for users to decide on the focus order of tabs when closing a tab. By default Opera always returns to the last active tab, and after more than two years with FF, and being accustomed to the focus changing to the next tab, I get frustrated to no end when I try using Opera. From what I see at the Opera forum, many Opera users want this feature, but the developers seem hard-nosed the other way.
 
Old 11-11-2005, 02:43 AM   #10
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,766

Rep: Reputation: 474Reputation: 474Reputation: 474Reputation: 474Reputation: 474
Should mention that env is used to manage and create environmental variables.
Exporting a global variable is not the same -it just makes the variable available to other scripts or programs called by the running program.

Try using double brackets and possibly the braces:

[[ "`ps ax | grep ${WINETEXT} ${PROXOMITRON}`" = "" ]] && wine $PROXOMITRON 2>/dev/null
 
Old 11-11-2005, 03:07 AM   #11
chesss
LQ Newbie
 
Registered: Nov 2005
Posts: 10

Rep: Reputation: 0
Quote:
By default Opera always returns to the last active tab, and after more than two years with FF, and being accustomed to the focus changing to the next tab, I get frustrated to no end when I try using Opera. From what I see at the Opera forum, many Opera users want this feature, but the developers seem hard-nosed the other way.
In a recent usability study by google this tab-switching behaviour is better than switch to next tab.
But if you still want that , then remeber Opera is crazily customizable, so you can easily use "close tab & switch to next tab" as a gesture or keyboard shortcut.
Goto preferences > shortcuts.
 
Old 11-11-2005, 05:59 AM   #12
Nobber
Member
 
Registered: Jun 2002
Location: Nova Scotia
Distribution: Debian (home), Kubuntu 7.04 (work)
Posts: 265

Rep: Reputation: 30
Woodsman, one problem I can see with your script is that the line

Code:
if [ "`ps ax | grep $WINETEXT $PROXOMITRON`" = "" ] ; then
will expand to

Code:
if [ "`ps ax | grep /usr/bin/wine-preloader /usr/bin/wine-kthread /mnt/nt_d/Proxomitron/Proxomitron.exe`" = "" ] ; then
which means grep is looking for the string "/usr/bin/wine-preloader" in the files /usr/bin/wine-kthread and /mnt/nt_d/Proxomitron/Proxomitron.exe and failing, which means that

Code:
`ps ax | grep $WINETEXT $PROXOMITRON`
always gives an empty string. What you probably should do is:

Code:
if [ "`ps ax | grep $PROXOMITRON`" = "" ] ; then
instead.

Last edited by Nobber; 11-11-2005 at 06:03 AM.
 
Old 11-11-2005, 10:48 PM   #13
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Original Poster
Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
Quote:
In a recent usability study by google this tab-switching behaviour is better than switch to next tab.
They obviously did not test me or all the people at the Opera forum who agree with me! What was that third category of lies that Samuel Clemens was so fond of? Statistics!

Mouse gestures? I don't like them. That's just me. All I want is to configure Opera to move to the next tab when I close a tab. I habitually open several tabs in the background when I read. When I close a tab Opera snaps back to the original tab that launched all of these tabs, so I have to manually click on the next tab. I am no fanboy of Firefox, but FF handles this configuration well. Additonally, mouse gestures must be a nightmare for people with palsies or nervous tremors in their hand and I know several people like that. Thus, there needs to be a simpler way to select the next tab when closing a tab.

Quote:
Should mention that env is used to manage and create environmental variables.
I'll look into that!

Quote:
Try using double brackets and possibly the braces...
I tried those double brackets and braces, but after Proxomitron had started and I again ran the script (snippet), the script failed to report that Proxo is already running.

Quote:
if [ "`ps ax | grep $PROXOMITRON`" = "" ] ; then
I tried that too. Same inconsistent results!

With a stroke of luck and persistent experimentation, this syntax finally worked:

[ -z "`ps ax | grep "$WINETEXT" | grep "$PROXOMITRON"`" ]

I tested several times, with both Proxo not running as well as already running. Worked perfectly each and every time! I don't understand all the subtleties of this solution, but I'm happy the string test finally works!

Thanks for all the help folks. Something clicked and I finally can move on to other projects.

I think I'll stand by my original thread title, however!
 
Old 11-12-2005, 06:31 AM   #14
chesss
LQ Newbie
 
Registered: Nov 2005
Posts: 10

Rep: Reputation: 0
Quote:
Mouse gestures? I don't like them. That's just me. All I want is to configure Opera to move to the next tab when I close a tab. I habitually open several tabs in the background when I read. When I close a tab Opera snaps back..
I agree , when opening pages in the background 'switch to next tab' is needed, but that s why opera is so good. You can assign a keyboard shortcut for closing and switch to next tab and another for normal operation.
and how exactly are you closing tabs? I guess it hs to be keyboard, since you don't like gestures.
btw what exactly wrong with mouse gestures? btw opera's gestures are way better than all-in-one.
 
Old 11-14-2005, 04:29 PM   #15
Woodsman
Senior Member
 
Registered: Oct 2005
Distribution: Slackware 14.1
Posts: 3,482

Original Poster
Rep: Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534Reputation: 534
Quote:
btw what exactly wrong with mouse gestures? btw opera's gestures are way better than all-in-one.
As I explained above, I simply do not like mouse gestures. I have enough crap in my life to memorize already without adding to that load. Additionally, as I explained above, gestures provide no usefulness for people with nerve tremors in their hands and more than likely mouse gestures are a nightmare to such people. FWIW, I don't use gestures in FF either, despite the extension being available.

I prefer to browse solely with conventional Close buttons. Overwhelmingly, however, I use the page context menu to close the page (menu item added by the TabMix extension). When my hand is on the mouse I do not want to reach for the keyboard to close a tab. The only time I want to reach for the keyboard is when I want to type something, as I am doing right now. My preference and that is all. When I open a bunch of tabs in the background, I want to read those tabs once I start reading them, and not be forced back to the original tab from which I launched those background tabs. My preference and that is all. I can do this without effort in FF.

I am comfortable with FF in Windows although I detest the overall XUL interface instead of using the native Windows interface as Opera does. I totally detest FF-GTK. Old dogs in August move faster than FF-GTK does in my KDE environment (and everything else responds quite nicely). Unfortunately, as long as the Opera developers refuse to provide this BASIC tab-focusing functionality, FF will remain my primary browser.

I am not a fan-boy of Opera or FF, Slackware nor Windows. I only want the tools that improve my perception of existence today. To paraphrase a well-known author, in the long run, we're all dead anyway!
 
  


Reply


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
little help with bash scripts sniff Programming 2 10-26-2005 05:17 PM
bash scripts hoffmanyew Programming 3 08-11-2005 01:27 AM
BASH script showing random behavior chatterbug89 Programming 12 07-19-2005 10:45 PM
strange sed/bash behavior mpdavig Programming 1 07-24-2004 02:27 AM
Bash Scripts Skute Programming 7 03-12-2004 10:17 AM


All times are GMT -5. The time now is 05:15 PM.

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