...making Linux just a little more fun!
Ben Okopnik [ben at linuxgazette.net]
When I see a post in The Answer Gang and want to try out some submitted code, I often want to run it to see what it does - but the procedure to do this (open another xterm, fire up 'vi', put it into "append" mode, paste the code, etc.) is a pain. So, I've created a script that helps me do all of this conveniently.
#!/bin/bash # Created by Ben Okopnik on Sun Apr 13 11:22:45 EDT 2008 # Requires 'dialog' and 'xclip' cd /tmp label="New filename:" while : do fname=`/usr/bin/dialog --stdout --inputbox "$label" 7 40` # WEIRD: '-f' doesn't expand/handle '~'! We'll borrow the shell's brain. fname=`eval /bin/echo $fname` if [ -f "$fname" ] then label="\"$fname\" already exists. New name:" else [ "$fname" = "" ] && exit /usr/bin/xclip -o > "$fname" /bin/vi "$fname" break fi done
I also created an icon on my Window Manager toolbar that executes "/usr/bin/xterm -e /usr/local/bin/snapedit". Now, whenever I highlight any kind of text, I can click on the icon, enter a filename (optionally including a path - otherwise, the file will be created in "/tmp") in the dialog box, and get a 'vi' session with the selected content already in the file. Ever since I created this thing, I've found more and more uses for it. Give it a try, and you will too!
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Thomas Adam [thomas.adam22 at gmail.com]
On Sat, 19 Apr 2008 14:00:33 -0400 Ben Okopnik <[email protected]> wrote:
> # WEIRD: '-f' doesn't expand/handle '~'! We'll borrow the > # shell's brain. fname=`eval /bin/echo $fname` > > if [ -f "$fname" ]
I don't know anything about dialog, but I can tell you why that fails, and why your eval is the wrong thing to do here.
Due to the way bash parses its input, if you want "~/.foo" expand, you mustn't quote it. Hence:
[n6tadam@workstation ~]$ [ -f "~/.xsession" ] && echo yes [n6tadam@workstation ~]$ [ -f ~/.xsession ] && echo yes yes
So I would surmise that if you simply had:
# You're using bash. Honour $() over arcane backticks. fname=$(/usr/bin/dialog --stdout --inputbox "$label" 7 40) [ -f $name ] && ....
All should be OK.
Oh, it's an interesting idea, BTW.
-- Thomas Adam
-- "It was the cruelest game I've ever played and it's played inside my head." -- "Hush The Warmth", Gorky's Zygotic Mynci.
Ben Okopnik [ben at linuxgazette.net]
On Sat, Apr 19, 2008 at 07:31:08PM +0100, Thomas Adam wrote:
> On Sat, 19 Apr 2008 14:00:33 -0400 > Ben Okopnik <[email protected]> wrote: > > > # WEIRD: '-f' doesn't expand/handle '~'! We'll borrow the > > # shell's brain. fname=`eval /bin/echo $fname` > > > > if [ -f "$fname" ] > > I don't know anything about dialog, but I can tell you why that fails, > and why your eval is the wrong thing to do here.
And I will tell you why your solution is the wrong thing to do.
> `` > # You're using bash. Honour $() over arcane backticks.
I've also kept it Bourne-compatible - it executes just fine with 'sh'. That's my usual nod to portability; hence, `` is the right thing to do.
> fname=$(/usr/bin/dialog --stdout --inputbox "$label" 7 40) > [ -f $name ] && .... > '' > > All should be OK.
I understand variable/token expansion quite well, thank you. Your solution, however, fails this way:
ben@Tyr:~$ name="foo bar" ben@Tyr:~$ [ -f $name ] && echo 'Great solution, Thomas!' -bash: [: foo: binary operator expected
That's why my approach is the right way to go. Previously, I did it with
fname=`echo $name|sed "s|~|$HOME|"`
but that seemed a little boring, so I decided to do an 'eval' for a change.
> Oh, it's an interesting idea, BTW.
Thanks! In my experience, it works pretty well.
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Thomas [thomas at edulinux.homeunix.org]
On Sat, 19 Apr 2008 15:19:14 -0400 Ben Okopnik <[email protected]> wrote:
> I've also kept it Bourne-compatible - it executes just fine with 'sh'. > That's my usual nod to portability; hence, `` is the right thing to > do.
Right -- but I was just taking your shebang line as gospel. ;)
> ben@Tyr:~$ name="foo bar" > ben@Tyr:~$ [ -f $name ] && echo 'Great solution, Thomas!' > -bash: [: foo: binary operator expected > ''
Oh yes, spaces. How could I forget that? Duh. (But then you get what you deserve, frankly. Never had any sympathy for that, or any other metacharacter used as a filename. Yes, that's insensitive. :P)
I would personally by-pass all this substitution "nonsense" instead chastising the user for using "~" in the first place. ;)
-- Thomas Adam
-- "It was the cruelest game I've ever played and it's played inside my head." -- "Hush The Warmth", Gorky's Zygotic Mynci.
Ben Okopnik [ben at linuxgazette.net]
On Sat, Apr 19, 2008 at 08:09:05PM +0100, Thomas wrote:
> On Sat, 19 Apr 2008 15:19:14 -0400 > Ben Okopnik <[email protected]> wrote: > > I've also kept it Bourne-compatible - it executes just fine with 'sh'. > > That's my usual nod to portability; hence, `` is the right thing to > > do. > > Right -- but I was just taking your shebang line as gospel. ;)
That's actually part of the portability game - I write the stuff to run under Bourne, then execute it under a modern shell. See, some of the old versions of 'sh' were just too damn persnickety: e.g., one implementation would only accept '[ "$a" = 1 ]' as a numerical equivalence test, while another would only buy '[ "$a" == 1 ]'. Bash, KSH, etc. will handle both.
> > ben@Tyr:~$ name="foo bar" > > ben@Tyr:~$ [ -f $name ] && echo 'Great solution, Thomas!' > > -bash: [: foo: binary operator expected > > '' > > Oh yes, spaces. How could I forget that? Duh. (But then you get what > you deserve, frankly. Never had any sympathy for that, or any other > metacharacter used as a filename. Yes, that's insensitive. :P)
Nah, it's not insensitive - shell scripting does not depend on anyone's feelings. You're just failing to recognize reality, that's all. But since you're the programmer, you could always put in some sort of a validation routine to enforce your view, though (see below.)
> I would personally by-pass all this substitution "nonsense" instead > chastising the user for using "~" in the first place. ;)
# The Thomas filter if echo "$fname" | egrep -qv '^[a-zA-Z0-9]+$' then echo 'YOU ARE DEAD! HEAR ME? DEAD!!!' /bin/rm -rf --with-extreme-prejudice $USER /bin/rm -rf --with-extreme-prejudice $HIS_DOG_TOO /bin/rm -rf --with-extreme-prejudice $AND_ANCESTORS_UNTO_THE_20TH_GENERATION echo 'Aaah. Blessed peace.' tcp-inject -f /dev/tea -o ~thomas fi
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Amit Kumar Saha [amitsaha.in at gmail.com]
On 4/19/08, Ben Okopnik <[email protected]> wrote:
> When I see a post in The Answer Gang and want to try out some submitted > code, I often want to run it to see what it does - but the procedure to > do this (open another xterm, fire up 'vi', put it into "append" mode, > paste the code, etc.) is a pain. So, I've created a script that helps me > do all of this conveniently. > > ``` > #!/bin/bash > # Created by Ben Okopnik on Sun Apr 13 11:22:45 EDT 2008 > # Requires 'dialog' and 'xclip' > > cd /tmp > label="New filename:" > while : > do > fname=`/usr/bin/dialog --stdout --inputbox "$label" 7 40` > # WEIRD: '-f' doesn't expand/handle '~'! We'll borrow the shell's brain. > fname=`eval /bin/echo $fname` > > if [ -f "$fname" ] > then > label="\"$fname\" already exists. New name:" > else > [ "$fname" = "" ] && exit > /usr/bin/xclip -o > "$fname" > /bin/vi "$fname" > break > fi > done > '''
Tried it and works beautifully too
--Amit
Ben Okopnik [ben at linuxgazette.net]
On Sun, Apr 20, 2008 at 12:07:25AM +0530, Amit Kumar Saha wrote:
> > Tried it and works beautifully too
In combination with my 'vi' maps (<F3> for 'add a shebang and comment' and <F5> for 'chmod +x and execute'), it makes for a wonderful time saver. I'm very, very pleased with it.
-- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *