UbuntuThis forum is for the discussion of Ubuntu Linux.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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?
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
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.
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.
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:
<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.
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.
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.
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)
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.
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.
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" )"
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.
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>"
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!
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.