LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Ubuntu
User Name
Password
Ubuntu This forum is for the discussion of Ubuntu Linux.

Notices


Reply
  Search this Thread
Old 09-18-2011, 01:23 PM   #1
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Rep: Reputation: 16
Openbox pipe menu script problems


Hi, I'm trying to write a pipe menu to generate a list so I can set my background. I run it in Xterm and it prints out everything in xml format, just like openbox calls for, but when I put it into a pipe menu, nothing comes up. Here is a copy of it:
Code:
#!/bin/bash

DIR="/home/nomad/Pictures/"
SUFFIX="png"
SUFFIX1="jpg"
SUFFIX2="jpeg"

echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
echo "<openbox_pipe_menu>"
#for i in "$DIR"*.$SUFFIX
#do
#	echo "<item label=\"${i}\"><action name=\"Execute\"><execute>feh --bg-scale ${i}</execute></action></item>"
#done

for i in "$DIR"*.$SUFFIX1
do
	echo "<item label=\"${i}\"><action name=\"Execute\"><execute>feh --bg-scale ${i}</execute></action></item>"
done

#for i in "$DIR"*.$SUFFIX2
#do
#	echo "<item label=\"${i}\"><action name=\"Execute\"><execute>feh --bg-scale ${i}</execute></action></item>"
#done
echo "</openbox_pipe_menu>"
I commented out the first and last for statements because I don't have any .png or .jpeg images. Any idea why it might not be working?

~Steve
 
Old 09-19-2011, 08:00 AM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
What, exactly, is a "pipe menu"?

In any case, if the script is printing its output correctly then that's probably not where the problem lies. It more likely has something to do with the way you're using it.


BTW, you can simplify your script down to a single loop, since the output is identical for each file type. Just tell it to iterate over anything it finds.
Code:
for i in "$DIR"*.$SUFFIX "$DIR"*.$SUFFIX1 "$DIR"*.$SUFFIX2
do
	echo "<item label=\"${i}\"><action name=\"Execute\"><execute>feh --bg-scale ${i}</execute></action></item>"
done
 
Old 09-19-2011, 11:07 AM   #3
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by David the H. View Post
What, exactly, is a "pipe menu"?

In any case, if the script is printing its output correctly then that's probably not where the problem lies. It more likely has something to do with the way you're using it.


BTW, you can simplify your script down to a single loop, since the output is identical for each file type. Just tell it to iterate over anything it finds.
Code:
for i in "$DIR"*.$SUFFIX "$DIR"*.$SUFFIX1 "$DIR"*.$SUFFIX2
do
	echo "<item label=\"${i}\"><action name=\"Execute\"><execute>feh --bg-scale ${i}</execute></action></item>"
done
Thanks for the simplified script, and a pipe menu is when, in Openbox, you have a menu that generates its entries based on script output. In my case, making a list of entries of the pictures in my "Pictures" directory to set as the background when I select that entry.
 
Old 09-19-2011, 11:36 AM   #4
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
I figured something like that. Is it a separate program, or it is something built into openbox?

So how do you use it then? What is the command syntax supposed to look like? How are you trying to call it? Have you ever done anything like this before, or is this the first time? Are you even sure it can be used in the way you want?

It seems most likely to me that the error is happening somewhere between it and the menu. Unless you got the xml syntax wrong somewhere.
 
Old 09-19-2011, 12:16 PM   #5
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by David the H. View Post
I figured something like that. Is it a separate program, or it is something built into openbox?

So how do you use it then? What is the command syntax supposed to look like? How are you trying to call it? Have you ever done anything like this before, or is this the first time? Are you even sure it can be used in the way you want?

It seems most likely to me that the error is happening somewhere between it and the menu. Unless you got the xml syntax wrong somewhere.
Pipe menus are built into openbox,
You use pipe menus by adding an entry to your menu.xml file like so:
Code:
<menu execute="/path/to/command" id="unique id" label="whatever">
well, the syntax of the pipe menu is just like any other menu, except it looks like this:
Code:
<openbox_pipe_menu>
 <item label="blahblahblah"><action name="Execute"><execute>blahblahblah</execute></action></item>
</openbox_pipe_menu>
Instead of
Code:
<menu id="[unique id here]" label="[whatever label you want]">
 menu stuff here
</menu>
See the first CODE box for how you call it
This is the first time I've done pipe menus for openbox, and yes, I'm sure it can be used this way, it's been done, only most other scripts for wallpaper menu generation are written in Python, and being the constant learning experience that linux is, I decided to try my hand at it. If we can't figure this out, I'll just download one from the openbox wiki.

Last edited by steviebob; 09-19-2011 at 12:25 PM.
 
Old 09-19-2011, 12:24 PM   #6
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by steviebob View Post
well, the syntax of the pipe menu is just like any other menu, except it looks like this:
Code:
<openbox_pipe_menu>
 <item label="blahblahblah"><action name="Execute"><execute>blahblahblah</execute></action></item>
</openbox_pipe_menu>
For the record, here's the output of my script:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<openbox_pipe_menu>
<item label="/home/nomad/Pictures/AbstractBlue.jpg"><action name="Execute"><execute>feh --bg-scale /home/nomad/Pictures/AbstractBlue.jpg</execute></action></item>
<item label="/home/nomad/Pictures/planets.jpg"><action name="Execute"><execute>feh --bg-scale /home/nomad/Pictures/planets.jpg</execute></action></item>
<item label="/home/nomad/Pictures/*.png"><action name="Execute"><execute>feh --bg-scale /home/nomad/Pictures/*.png</execute></action></item>
<item label="/home/nomad/Pictures/*.jpeg"><action name="Execute"><execute>feh --bg-scale /home/nomad/Pictures/*.jpeg</execute></action></item>
</openbox_pipe_menu>

Last edited by steviebob; 09-19-2011 at 12:26 PM.
 
Old 09-19-2011, 01:48 PM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Well, assuming I understand it, I can't really see anything wrong with the syntax offhand. Is the xml version line necessary?

Oh, and my apologies. It looks like you'll need to add "shopt -s nullglob" to your script to prevent the non-matching glob patterns from printing.
 
Old 09-19-2011, 02:04 PM   #8
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by David the H. View Post
Well, assuming I understand it, I can't really see anything wrong with the syntax offhand. Is the xml version line necessary?

Oh, and my apologies. It looks like you'll need to add "shopt -s nullglob" to your script to prevent the non-matching glob patterns from printing.
Ah. Thanks for that, I was trying to think of how I'd get rid of those... anyway, removing the xml version line didn't help, still nothing showing up in the menu. Any other ideas? Like I said, if we can't figure this out, I'll just use a pre-made script.
 
Old 09-19-2011, 07:42 PM   #9
qlue
Member
 
Registered: Aug 2009
Location: Umzinto, South Africa
Distribution: Crunchbangified Debian 8 (Jessie)
Posts: 747
Blog Entries: 1

Rep: Reputation: 172Reputation: 172
Quote:
Originally Posted by steviebob View Post
Ah. Thanks for that, I was trying to think of how I'd get rid of those... anyway, removing the xml version line didn't help, still nothing showing up in the menu. Any other ideas? Like I said, if we can't figure this out, I'll just use a pre-made script.
I'd suggest that you try dissecting one of those pre-made scripts to see how they did it. Also, try posting this in the Crunchbang forum as well.
 
Old 09-19-2011, 09:07 PM   #10
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by qlue View Post
I'd suggest that you try dissecting one of those pre-made scripts to see how they did it. Also, try posting this in the Crunchbang forum as well.
Thanks for the tip, glue. I'll post in the #! forums. Also, from what I can tell, the python scripts do the same thing my shell script does, except, you know, it's in python and not in bash. (I have some experience in python from years past)
 
Old 09-20-2011, 11:02 AM   #11
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Okay, I have some good news. Turns out I had the menu pointing to the wrong script. When I fixed the menu, it still didn't work, so I decided to try "printf" instead of "echo" in the script. Turns out that works. Also, when it ran, it would always display the full path of the file instead of just the name, so I ran it through "sed" to get rid of the file path. Here's an updated version of the script so anyone using Openbox can modify it and use it themselves:
Code:
#!/bin/bash

DIR="/background/directory/here/"
SUFFIX="png"
SUFFIX1="jpg"
SUFFIX2="jpeg"

shopt -s nullglob
printf "<openbox_pipe_menu>"
for i in "$DIR"*.$SUFFIX "$DIR"*.SUFFIX1 "$DIR"*.SUFFIX2
do
     N=`echo $i| sed 's/.*\///'
     printf "<item label=\"$N\"><action name=\"EXECUTE\"><execute>feh --bg-scale ${i}</execute></action></item>
done
printf "</openbox_pipe_menu>"
The only problem I'm having is that when you have xcompmgr running, it makes the screen essentially go blank, and the only way to really fix that is to alt-tab to the programs to make them show up again. I'd put "&& xrefresh" but I get an xml error whenever that happens. I'll just run it through cron and tell it to refresh the screen every second or so.

Last edited by steviebob; 09-20-2011 at 11:29 AM.
 
Old 09-20-2011, 02:34 PM   #12
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Good to hear it. So the problem was embedded newlines then?

There's no need to use sed here, by the way. When extracting substrings from the contents of variables, you can usually use built-in parameter expansion instead.

Code:
$ i='/full/path/to/foo.txt'
$ echo "${i##*/}"
foo.txt
Although of course the reason you're getting the full path is because you're using the $DIR variable in the globbing pattern. You could avoid this by cd'ing into the directory instead, and globbing directly from there.
Code:
cd "$DIR"
for i in *.$SUFFIX *.$SUFFIX1 *.$SUFFIX2; do
	....
Also...

1) $(..) is highly recommended over `..`.
2) Use a here string rather than a pipe, to avoid forking yet another subshell.
3) sed can use any delimiter in the s command, not just /, so you can avoid backslash escaping.
4) There's also a dedicated basename command you could use instead.
5) Why not just reuse the i variable, rather than create a new one?

So even with the original solution, these would be better:
Code:
N=`echo $i| sed 's/.*\///'	#change this to...

i="$( sed 's|.*/||' <<<"$i" )"	#or this...

i="$( basename "$i" )"
 
Old 09-20-2011, 04:15 PM   #13
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by David the H. View Post
Good to hear it. So the problem was embedded newlines then?

There's no need to use sed here, by the way. When extracting substrings from the contents of variables, you can usually use built-in parameter expansion instead.

Code:
$ i='/full/path/to/foo.txt'
$ echo "${i##*/}"
foo.txt
Although of course the reason you're getting the full path is because you're using the $DIR variable in the globbing pattern. You could avoid this by cd'ing into the directory instead, and globbing directly from there.
Code:
cd "$DIR"
for i in *.$SUFFIX *.$SUFFIX1 *.$SUFFIX2; do
	....
Also...

1) $(..) is highly recommended over `..`.
2) Use a here string rather than a pipe, to avoid forking yet another subshell.
3) sed can use any delimiter in the s command, not just /, so you can avoid backslash escaping.
4) There's also a dedicated basename command you could use instead.
5) Why not just reuse the i variable, rather than create a new one?

So even with the original solution, these would be better:
Code:
N=`echo $i| sed 's/.*\///'	#change this to...

i="$( sed 's|.*/||' <<<"$i" )"	#or this...

i="$( basename "$i" )"
Thanks for the tips. It's always good to optimize code. Also it's helping me learn more about bash scripting. I'll make those changes to the script.

Aaaand....

Here is the optimized code:
Code:
#!/bin/bash

DIR="/home/nomad/Pictures/"
SUFFIX="png"
SUFFIX1="jpg"
SUFFIX2="jpeg"

shopt -s nullglob
printf "<openbox_pipe_menu>"
cd "$DIR"
for i in *.$SUFFIX1 *.$SUFFIX *.$SUFFIX2
do
        printf "<item label=\"$i\"><action name=\"Execute\"><execute>feh --bg-scale $DIR$i</execute></action></item>"
done
printf "</openbox_pipe_menu>"

Last edited by steviebob; 09-20-2011 at 04:22 PM.
 
Old 09-20-2011, 06:24 PM   #14
steviebob
Member
 
Registered: Jan 2010
Location: Arkansas
Distribution: Slackware-Current, LFS
Posts: 136

Original Poster
Rep: Reputation: 16
Well, my problem is now solved. Also, wrote a simple little script I put into /usr/bin/ called "refresher". I chose the name because it was a while loop that refreshes the screen once every second, but the screen flashed and all because of it, so I changed it to this:

Code:
#!/bin/bash

feh --bg-scale $1
xrefresh
This gets around the problem of everything on the screen disappearing until you alt+tab to it while running xcompmgr. Just replace "feh --bg-scale" with "refresher" in the output. Thanks for all the help you guys gave me!
 
  


Reply



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
LXer: Four great pipe menus for Openbox LXer Syndicated Linux News 0 07-29-2011 12:00 PM
[SOLVED] openbox - menu.xml - syntax error quexxon-12 Linux - Software 3 06-04-2011 01:03 AM
Openbox Applications Menu MTK358 Linux - Desktop 2 10-10-2010 07:42 AM
OpenBox menu.xml error Cmdr_K00n Linux - Newbie 1 06-22-2004 06:41 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Ubuntu

All times are GMT -5. The time now is 04:44 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration