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?
4 Answers 4
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– glenn jackman2015年10月07日 13:57:34 +00:00Commented Oct 7, 2015 at 13:57
-
3@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.2015年10月07日 13:58:43 +00:00Commented Oct 7, 2015 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 calledSomejuan– Somejuan2015年10月07日 14:17:30 +00:00Commented Oct 7, 2015 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 runcsh script.csh
orbash script.csh
.2015年10月07日 14:19:29 +00:00Commented Oct 7, 2015 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– Somejuan2015年10月07日 14:34:20 +00:00Commented Oct 7, 2015 at 14:34
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– Somejuan2015年10月07日 14:27:18 +00:00Commented Oct 7, 2015 at 14:27
-
1@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 allsh
interpreters. You'd only want to usebash
if you wanted your scripts to use features specific tobash
.Stéphane Chazelas– Stéphane Chazelas2015年10月07日 15:07:24 +00:00Commented Oct 7, 2015 at 15:07 -
1@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 kshprint
builtin (not available inbash
), but it doesn't make that script non-POSIX, because thatprint foo
may just as well have been intended as calling the system'sprint
command if there's one.Stéphane Chazelas– Stéphane Chazelas2015年10月07日 15:09:47 +00:00Commented Oct 7, 2015 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– Wildcard2015年10月08日 02:57:59 +00:00Commented Oct 8, 2015 at 2:57
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– Somejuan2015年10月07日 14:39:19 +00:00Commented Oct 7, 2015 at 14:39
-
While probably not comprehensive, this paper does a nice job of showing how
sh
,ksh88
,ksh93
, andbash
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– James Sneeringer2015年10月07日 16:26:47 +00:00Commented Oct 7, 2015 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.htmlschily– schily2015年10月15日 12:38:38 +00:00Commented Oct 15, 2015 at 12:38
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.
bash
is notksh
../files
, but you don't need to; in the script above, you can say simplyfiles
. (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 yourmv
command can bemv "$f" "files/$(basename "$f" .ksh).bash"
. (4) You can simplify it even further, tomv "$f" "${f%.ksh}.bash"
. (5) Be careful with search and replace, lest you change "workshop" to "worbashop".