0

Since both ksh and bash are based upon sh many Korn Shell scripts (ksh) will simply run as Bourne-again Shell scripts (bash) once the shebang and file extension are changed,

and you call $ bash script.bash instead of $ ksh script.ksh.

I have a basic script to replace any occurrence of ksh in a directory called "files" and changes file extensions for the scripts.

#!/bin/bash/

#replace instances
find ./files -type f - exec sed -i.bak "s/ksh/bash/g" {} \;

#Change extensions
for f in ./files/*.ksh;
  do mv "$f" "./files/""$(basename "$f" .ksh).bash"
done

#Clean up
rm ./files/*.bak

This script works and does what is described above, but is it sufficient for converting any ksh script to bash, or are there conditions which I have not accounted for?

  • 5
    I feel confident in saying there are conditions which you have not accounted for. But I'm not going to spend a lot of time enumerating the ways bash is not ksh. – Elliott Frisch Oct 7 '15 at 13:36
  • I would not doubt that I had missed some, but for converting multiple relatively simple scripts would this likely be sufficient? – Somejuan Oct 7 '15 at 13:44
  • 1
    If you don't want the "*.bak" files, don't create them in the first place. – glenn jackman Oct 7 '15 at 13:56
  • Do any of these programs use array variables? – glenn jackman Oct 7 '15 at 13:58
  • 1
    (1) There's no harm in saying ./files, but you don't need to; in the script above, you can say simply files. (2) -exec has the same syntax structure as -type — no space between the - and the keyword. (3) The double-double-quote sequence "" generally doesn't do anything (unless it is inside single quotes, in which case it is just two quoted characters), so your mv command can be mv "$f" "files/$(basename "$f" .ksh).bash". (4) You can simplify it even further, to mv "$f" "${f%.ksh}.bash". (5) Be careful with search and replace, lest you change "workshop" to "worbashop". – G-Man Says 'Reinstate Monica' Oct 7 '15 at 14:47
5

The script isn't really doing anything useful. The extension is irrelevant and the shebang line is ignored if you run with bash explicitly. You can get the exact same thing as what your script does if you just run:

bash script.ksh

The issue is the differences in syntax. That's what you will need to fix, otherwise, just run the scripts with bash and be done with it.

  • bad advice. what happens when the next person comes along to maintain the programs? If they are supposed to run with bash, at the minimum change the shebang line. – glenn jackman Oct 7 '15 at 13:57
  • 2
    @glennjackman no worse than what would happen if the OP ran their script. My main point is that the premise is wrong here and that changing the extension ad shebang lines is basically pointless. That's why I say that what needs to be fixed is the syntax where different. – terdon Oct 7 '15 at 13:58
  • This is beneficial, I was curious about the order of precedence when It came to these three factors; the shebang, extension, and command being explicitly called – Somejuan Oct 7 '15 at 14:17
  • @Somejuan the extension is completely irrelevant. The only place it might be used is in your editor to determine the correct syntax highlighting mode. The shebang sets the interpreter when you run script.csh but is ignored if you run csh script.csh or bash script.csh. – terdon Oct 7 '15 at 14:19
  • @terdon That is good to know considering that some of the scripts are executable and not explicitly called by a command. – Somejuan Oct 7 '15 at 14:34
3

bash only implements a subset of the features of ksh93. While it implements most of the features of ksh88, for some of them it does it differently and not all features are enabled by default.

For instance, aliases in bash are not expanded when non-interactive, the ksh extended globs are not enabled by default, bash has no print builtin, can't define arrays with set -A, co-processes are invoked and used differently...

So, unless those ksh scripts are very simple and are basically POSIX sh compatible (a well defined subset of the command subset of bash and the various ksh implementation syntax), it's likely they won't run properly with bash.

Now, since 2000, ksh93 is open source and available for free on most operating systems (and for the most part backward compatible with ksh88). For ksh88 scripts, pdksh and modern derivatives like mksh are also generally enough.

All of them are generally a lot more efficient than bash, so I can't see why you would want to have those scripts interpreted by bash rather than the interpreter they've been originally written for.

Even zsh would be a better choice than bash as it has a ksh emulation mode.

  • I have been asked to convert them so I was looking for an automated mechanism to do so. If I could test the original scripts for POSIX sh compatibility then they would likely work? assuming they passed this test. – Somejuan Oct 7 '15 at 14:27
  • @Somejuan, even if they were POSIX sh compatible, it would make little sense to have them interpreted by bash. bash is probably the least efficient of all sh interpreters. You'd only want to use bash if you wanted your scripts to use features specific to bash. – Stéphane Chazelas Oct 7 '15 at 15:07
  • @Somejuan, and testing for POSIX sh compatibility is something that would be based on heuristics and not fool-proof. For instance print foo in a ksh script invokes the ksh print builtin (not available in bash), but it doesn't make that script non-POSIX, because that print foo may just as well have been intended as calling the system's print command if there's one. – Stéphane Chazelas Oct 7 '15 at 15:09
  • @Somejuan, if you were "asked to convert them" at work, it most likely wasn't so you could do a semi-functional automated conversion which will leave things breaking later on. That's not as bad as being hired as a book translator and outsourcing your work to Google translate, but there is a similarity. You will likely have to convert each script by hand to call it a job well done. – Wildcard Oct 8 '15 at 2:57
0

bash and ksh do share a big part of the syntax, so many scripts will work in both. However, there are features in ksh that bash doesn't support (e.g. regular expressions), and any script using those features is likely to misbehave. It really doesn't matter whether your scripts are simple - a regular expression is often used in simple if conditions.

There is really no way a simple script could fix these quirks for you. Re-writing regular expressions is not a task that is easy to automate. What you can do automatically is to run all the scripts in a chroot environment and see if bash complains about any syntax errors. Still, you can't be 100% sure to detect all issues this way, some may remain hidden (syntax could be valid but mean different things in bash and ksh).

  • is there anywhere where I can find a complete list of the unsupported features? If need be I could manually examine each script. – Somejuan Oct 7 '15 at 14:39
  • While probably not comprehensive, this paper does a nice job of showing how sh, ksh88, ksh93, and bash differ on numerous Unix/Linux platforms. It's about 5 years old and assumes Bash 3.x (the author tested on CentOS 5.4), so some things that it notes Bash as lacking are no longer the case with Bash 4.x (e.g. associative arrays). – James Sneeringer Oct 7 '15 at 16:26
  • The paper is nice, but it incorrectly claims that FreeBSD comes with a Burne Shell. This is not true and the man page from FreeBSD differs from the original Bourne Shell man page at: schillix.sourceforge.net/man/man1/sh.1.html – schily Oct 15 '15 at 12:38
0

A more strict approach would be to run checkbashisms on your scripts to check if they are in fact sh-compliant. Both bash and ksh will be able to run such scripts just fine. But again, in case of any issues you will have to fix your scripts manually.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.