Always wondered what is the difference between these four shells? Here's the answer. …
Showing posts with label The Shell Programming Language. Show all posts
Showing posts with label The Shell Programming Language. Show all posts
Thursday, December 19, 2013
differences between Bourne shell, Korn shell, C shell, and bash
http://www.efytimes.com/e1/creativenews.asp?edid=123101 :
Labels:
bash,
Korn shell,
The Shell Programming Language
Wednesday, December 18, 2013
shell code and useless use of "ls *.tar"
Consider this code (I came across such Korn shell script code recently):
Please forgive me the naming here! I was happy to take this note anyway.
TARFILE=$(ls -1 /tmp/*.tar)According to http://partmaps.org/era/unix/award.html#ls you ought to replace the ls with a glob, e.g. like this:
[[ -s /tmp/*.tar ]] && set -A tarfiles /tmp/*.tarInstead you may want to enquire ${#tarfiles[@]}, i.e. the number of files globbed.
for TARFILE in "${tarfiles[@]}"
do
: # ...
done
Please forgive me the naming here! I was happy to take this note anyway.
Wednesday, November 13, 2013
migrated a Korn shell script using "Extended Pattern Matching" to bash
https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
I had to "shopt -s extglob" for that.
I inserted the shopt line rather close to the case statement, where the Extended Pattern Matching gets employed. That was inside a loop. That had no effect, but it didn't say so. I rather threw some weird error messages. I reduced the code around the causing line to its minimum, occasionally moved the shopt to outside the loop, and it worked. If it had only been that straigt …
I had to "shopt -s extglob" for that.
I inserted the shopt line rather close to the case statement, where the Extended Pattern Matching gets employed. That was inside a loop. That had no effect, but it didn't say so. I rather threw some weird error messages. I reduced the code around the causing line to its minimum, occasionally moved the shopt to outside the loop, and it worked. If it had only been that straigt …
Labels:
bash,
Korn shell,
The Shell Programming Language
Tuesday, November 5, 2013
the bash's "nullglob" is rather nice to use
http://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
w/o this command line:
With the above command line executed already, this command line will print file infos of /etc/passwd and ignore the unsuccessful other two glob patterns:
I tried to find something comparable in the Korn Shell, but I wasn't successful.
w/o this command line:
$ shopt -s nullgloba glob pattern, that does not successfully evaluate to existing file names, gets literally resolved to a file name identical to the glob pattern.
With the above command line executed already, this command line will print file infos of /etc/passwd and ignore the unsuccessful other two glob patterns:
$ ll /etc/passwd /etc/passwd? /etc/passwd??In interactive mode you may want to see the error messages, within a shell script supplying all three parameters to a "for f in …" loop, you will want the unresolving ones to get ignored.
$ for f in /etc/passwd /etc/passwd? /etc/passwd??; do echo $f; doneWell, at least in my script today I found this option rather useful.
I tried to find something comparable in the Korn Shell, but I wasn't successful.
Wednesday, February 20, 2013
O'Reilly Media book: bash Pocket Reference
bash Pocket Reference:
You need to know how to work with the bash shell if you want to get to the heart of Unix systems, including Linux and Mac OS X. Now covering the most recent version of bash, this concise little book puts all of the essential information about bash at your fingertips. You'll quickly find answers to annoying questions that always come up when you're writing shell scripts -- What characters do you need to quote? How do you get variable substitution to do exactly what you want? How do you use arrays? -- and much more.
You need to know how to work with the bash shell if you want to get to the heart of Unix systems, including Linux and Mac OS X. Now covering the most recent version of bash, this concise little book puts all of the essential information about bash at your fingertips. You'll quickly find answers to annoying questions that always come up when you're writing shell scripts -- What characters do you need to quote? How do you get variable substitution to do exactly what you want? How do you use arrays? -- and much more.
Labels:
bash,
OReilly,
The Shell Programming Language
Tuesday, February 19, 2013
ksh88 man page
www2.research.att.com/sw/download/man/man1/ksh88.html man page
- NAME
- SYNOPSIS
- DESCRIPTION
- * Definitions
- * Commands
- * Comments
- * Aliasing
- * Tilde Substitution
- * Command Substitution
- * Process Substitution
- * Parameter Substitution
- * Blank Interpretation
- * File Name Generation; bash: shopt extglob on # "extended globbing"
- * Quoting
- * Arithmetic Evaluation
- * Prompting
- * Conditional Expressions
- * Input/Output
- * Environment
- * Functions
- * Jobs
- * Signals
- * Execution
- * Command Re-entry
- * In-line Editing Options
- * Emacs Editing Mode
- * Vi Editing Mode
- * Input Edit Commands
- * Motion Edit Commands
- * Search Edit Commands
- * Text Modification Edit Commands
- * Other Edit Commands
- * Special Commands: …, set, …
- * Invocation
- * rksh88 Only
- EXIT STATUS
- FILES
- SEE ALSO
- CAVEATS
DESCRIPTION : Functions :
… Function identifiers can be listed with the -f or +f option of the typeset special command. …
Wednesday, October 17, 2012
shell: basename and dirname through Parameter Expansion
If you want to have basename and dirname a little faster through shell builtins, you may want to try these in bash or Korn Shell:
- basename: ${file##*/}
- dirname: ${file%/*}
I don't really recommend to use these substitutes, I still find basename and dirname quite readable and I am not using them in a loop anyway.
Monday, October 15, 2012
Saturday, October 6, 2012
O'Reilly Media book: Learning the Korn Shell, 2nd Edition
- Learning the Korn Shell, 2nd Edition - O'Reilly Media (They don't offer it as an e-book. What a pity.)
- kornshell.com
- http://kornshell.com/doc/
- KornShell 88 Manual Page [Link] (-> get a git clone as described here and improve the links etc.; are their true man page sources?)
- KornShell 93 Manual Page [Link]
Q: The ksh on "your" AIX – is it ksh88 or ksh93?
A: Well … the ksh on "my" AIX knows the "whence" builtin without "-a", so I think it's a ksh88, because ksh93 would know "whence -a".
(This paragraph will go to another article on ksh. (TBD))
Sunday, August 12, 2012
O'Reilly Media book: Classic Shell Scripting
nice scripts shown there and available in the sample code:
- pathfind.sh – rather similar to my own find_file_on_PATH.sh
- show-identical-files.sh – rather similar to my own group_by_content.sh – but has a problem with "md5sum"
- puser.sh
- …
Wednesday, July 20, 2011
shell programming: "for" loops vs. "while" loops and scope of variables created within loop bodies
Variables, that you create (by assignment) within loop bodies, are well visible outside the loop body. This is valid for both kinds of loop.
CAVEAT:
If the "while" loop reads from a pipe, the "while" loop is executed within a subshell, i.e. the scope of the variables within the loop ends with the loop.
Example:
x=a
echo hello |
while read l
do
x=b
done
echo "x=$x"
What's the output of this echo?
x=a
Example:
x=a
for l in hello
do
x=b
done
echo "x=$x"
What's the output of this echo?
x=b
Friday, July 9, 2010
want to get signalled, when a command line job on your computer is done?
I have a long list of cpanm jobs,
don't want to put them in a batch all toghether,
and want to get signalled, when each of them is done:
Update:
Yes, notify-send is far, far, far superiour, growlnotify on OS X.
Thanks for the pointers!
don't want to put them in a batch all toghether,
and want to get signalled, when each of them is done:
$ while true; do beep; doneIn my case the beep is acutally just the flashing of an xterm window.
Update:
Yes, notify-send is far, far, far superiour, growlnotify on OS X.
Thanks for the pointers!
GNU Coreutils "seq"
the manual page.
Why do I keep forgetting the name of this wonderful little helper?
seq prints a sequence of numbers to standard output. Synopses:
Why do I keep forgetting the name of this wonderful little helper?
seq prints a sequence of numbers to standard output. Synopses:
seq [option]... last seq [option]... first last seq [option]... first increment lastseq prints the numbers from first to last by increment. By default, each number is printed on a separate line. When increment is not specified, it defaults to ‘1’, even when first is larger than last. first also defaults to ‘1’. So
seq 1
prints ‘1’, but seq 0
and seq 10 5
produce no output. Floating-point numbers may be specified (using a period before any fractional digits).best practices in shell script programming – colons
My snipplet for an if/then/else in shell scripts looks like this:
And the colons usually remain there for the remainder of the life of that code.
Have you noticed, that the youngsters, that talk about snipplets nowadays seriously think, they invented them? True, I guess, they created the term. Just the term.
if true
then :
else :
fiThe colons make that code syntactically complete, w/o the colons you run into a syntax error. The colon is the "null op" of (Bourne) shell scripting.
And the colons usually remain there for the remainder of the life of that code.
Have you noticed, that the youngsters, that talk about snipplets nowadays seriously think, they invented them? True, I guess, they created the term. Just the term.
best practices in shell script programming – double quotes
You do know the result of this:
a=A; echo $a
But are you just as sure here?
a=A; b=B; echo $a.$b
That depends on the shell, you are using. So I suggest you better write it this way:
a=A; b=B; echo ${a}.${b}
Enclosing variable names in curly braces is quite often a good idea.
Look at the following piece of code:
case $var in
x*)
echo var starts with x
;;
*)
echo var starts with something else
;;
esac
Looks alright, doesn't it?
No, it's does not. If that variable had not been assigned a value before or is of zero length, you will see an ugly syntax error occur.
Therefore enclose the variable in double quotes like here:
case "$var" in
x*)
echo var starts with x
;;
*)
echo var starts with something else
;;
esac
There is no good excuse for not doing it anywhere. It may look ugly and unnecessary, but it will help. That's the way shell scripting is. I learned this from Jürgen Gulbins around 1987, when I enjoyed working for him. This series of articles is dedicated to him. I owe him a lot.
best practices in shell script programming
You do know the result of this:
a=A; echo $aBut are you just as sure here?
a=A; b=B; echo $a.$b
That depends on the shell, you are using. So I suggest you better write it this way:
a=A; b=B; echo ${a}.${b}Enclosing variable names in curly braces is quite often a good idea.
Friday, July 2, 2010
App::perlbrew - Manage perl installations in your $HOME or wherever you want
Prerequisites:
- $ zypper install patch
- $ zypper install gcc
- …
Caveat:
- yes, "perlbrew install" occasionally and too often needs "--force" and even "--notest", don't be too surprised! my "5.14.2" and also my "5.16.1" needed it
- …
Main links:
- www.perlbrew.pl
- $ perlbrew
- $ perlbrew help
- http://search.cpan.org/perldoc?App::perlbrew – this one tells you, how to upgrade perlbrew:
$ export PERLBREW_ROOT=/opt/perlbrew
$ curl -kL http://install.perlbrew.pl | bash
# or maybe like this:
$ perlbrew self-upgrade
- https://metacpan.org/module/App::perlbrew
- https://metacpan.org/module/perlbrew : list-modules, how to migrate modules together with cpanm, …
- http://www.perl.org/pub/2010/03/testing-perl-5120-rc-1-with-appperlbrew.html (a little outdated)
- Perlbrew and my shebang line [Link]:
The developer/maintainer does not have in mind this use case as the main use case!! But it is my main use case.
What to do after installing a new perl, that you consider your new stable perl?
I decided to make use of $PERLBREW_ROOT, as I want to keep my home $HOME minimial, just data and scripts, no big files, they all go to other disks. And right, my home directory is on an encrypted partition, and this sort of stuff certainly does not get encrypted.
So actually this is according to best practices for shell programming the right way (for me) to do it, and now this code is of course included in my $HOME/.profile:
# for perl's App::perlbrew :
export PERLBREW_ROOT=/usr/local/perlbrew # on my Linux boxes
export PERLBREW_ROOT=/sw/perlbrew # on my Mac box(es)
source $PERLBREW_ROOT/etc/bashrc
##export PATH=$PERLBREW_ROOT/bin:$PERLBREW_ROOT/perls/current/bin:${PATH}
path_prepend $PERLBREW_ROOT
path_prepend $PERLBREW_ROOT/perls/current
BTW: always "$ hash -r" after switching, so you avoid getting certain perl resp. perlbrew related error messages like this one and a few others (confusion of the right installation directory):
To be continued …
Update 2011-10-16:
On my Mac running Lion I was able to perlbrew these releases of perl
Looks like OS X got targeted as a serious platform for perl development only rather recently.
…
Update 2012-10-07: A historic note: I first looked into perlbrew in the context of "biz-JG".
What to do after installing a new perl, that you consider your new stable perl?
$ perlbrew alias create perl-RELEASE stable
# resp.
$ perlbrew alias -f create perl-RELEASE stable
# use this shebang line with $PERLBREW_ROOT expanded [Link]:
#! $PERLBREW_ROOT/perls/stable/bin/perl
$ perlbrew switch stable # this will be our usual starting point!!!
# but "perlbrew list-modules" does not work on such an alias, so "perlbrew use" to a non-alias before!
- Have a serious look at "$ perlbrew help" once in a while!!!
I decided to make use of $PERLBREW_ROOT, as I want to keep my home $HOME minimial, just data and scripts, no big files, they all go to other disks. And right, my home directory is on an encrypted partition, and this sort of stuff certainly does not get encrypted.
$ export PERLBREW_ROOT=/usr/local/perlbrewTherefore my perlbrew is installed as:
/usr/local/perlbrew/bin/perlbrewThey suggest, that my $HOME/.bashrc should "source" their .../etc/bashrc, but for the time being I let my $HOME/.profile do this, as IMHO this is right place.
So actually this is according to best practices for shell programming the right way (for me) to do it, and now this code is of course included in my $HOME/.profile:
# for perl's App::perlbrew :
export PERLBREW_ROOT=/usr/local/perlbrew # on my Linux boxes
export PERLBREW_ROOT=/sw/perlbrew # on my Mac box(es)
source $PERLBREW_ROOT/etc/bashrc
##export PATH=$PERLBREW_ROOT/bin:$PERLBREW_ROOT/perls/current/bin:${PATH}
path_prepend $PERLBREW_ROOT
path_prepend $PERLBREW_ROOT/perls/current
BTW: always "$ hash -r" after switching, so you avoid getting certain perl resp. perlbrew related error messages like this one and a few others (confusion of the right installation directory):
bash: …: No such file or directoryI successfully brewed 5.10.1 and 5.12.1 on openSUSE-11.2, but on OS X Snow Leopard I only brewed 5.12.1 successfully, brewing 5.10.1 failed.
To be continued …
Update 2011-10-16:
On my Mac running Lion I was able to perlbrew these releases of perl
- perl-5.15.3 and
- perl-5.14.2
- but not perl-5.12.4, 5.10.1, 5.8.9, 5.6.2
but that seems more than sufficient to me.
Looks like OS X got targeted as a serious platform for perl development only rather recently.
…
Update 2012-10-07: A historic note: I first looked into perlbrew in the context of "biz-JG".
Subscribe to:
Posts (Atom)