Tux

...making Linux just a little more fun!

2-cent tip: Snapedit

Ben Okopnik [ben at linuxgazette.net]


Sat, 19 Apr 2008 14:00:33 -0400

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 *


Top    Back


Thomas Adam [thomas.adam22 at gmail.com]


Sat, 19 Apr 2008 19:31:08 +0100

On Sat, 19 Apr 2008 14:00:33 -0400 Ben Okopnik <ben@linuxgazette.net> 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.


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 19 Apr 2008 15:19:14 -0400

On Sat, Apr 19, 2008 at 07:31:08PM +0100, Thomas Adam wrote:

> On Sat, 19 Apr 2008 14:00:33 -0400
> Ben Okopnik <ben@linuxgazette.net> 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 *


Top    Back


Thomas [thomas at edulinux.homeunix.org]


Sat, 19 Apr 2008 20:09:05 +0100

On Sat, 19 Apr 2008 15:19:14 -0400 Ben Okopnik <ben@linuxgazette.net> 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.


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 19 Apr 2008 15:54:30 -0400

On Sat, Apr 19, 2008 at 08:09:05PM +0100, Thomas wrote:

> On Sat, 19 Apr 2008 15:19:14 -0400
> Ben Okopnik <ben@linuxgazette.net> 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 *


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Sun, 20 Apr 2008 00:07:25 +0530

On 4/19/08, Ben Okopnik <ben@linuxgazette.net> 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


Top    Back


Ben Okopnik [ben at linuxgazette.net]


Sat, 19 Apr 2008 15:21:50 -0400

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 *


Top    Back