How to check differences in bash and other shell profiles - linux

I have some shell scripts which I run in my Linux/AIX machine with bash profile. Now my bash profile is going to be remove, and I will have Korn shell (ksh) or the C shell (csh). How to verify whether my scripts will run fine in Korn shell (ksh) or C shell (csh), even after bash shell is removed. Also, is there any differnce in commonly used commands between bash and other (ksh, csh). Is there command to check, which shell is getting used while running the shell script.

First of all, this is not a problem, the default shell of your account is irrelevant. As long as bash is installed on the machine, you can use it to run your code. Either add a shebang line as the first line of your script:
#!/usr/bin/env bash
Or, explicitly run the script with bash:
$ /bin/bash /path/to/script.sh
As for the differences, yes there are many. A script written for bash will not run in csh, their syntax is completely different. It might run on ksh but that will depend on your script. Not all features of the two shells are the same. For example:
$ cat test.sh
var="foo";
echo $var;
$ bash ./test.sh
foo
$ ksh ./test.sh
foo
$ csh ./test.sh
var=foo: Command not found.
var: Undefined variable.
As you can see above, var=foo runs correctly in ksh (which is part of the bourne shell family) but fails for csh. Basically, think of each shell as its own programming language. You wouldn't expect the python interpreter to be able to run a perl program, why do you expect one shell to be able to run a script written for another?

OP writes bash is going to be removed.
If you really cannot get bash installed. start each script with #!/bin/ksh and check for syntax problems:
ksh -n migrated_script
When you use bash/linux specific things you need to address them:
AIX will be "missing" flags on commands like find (changed last hour...) and ksh itself is also different.
Do not try csh, that is completely different.

Related

Running bash script on multiple shells

So I was trying to create a script on bash shell, I came to know that the script doesn't run on ksh or dash shells. So my question is how you make a script to run on all 3 (bash, dash & ksh) shells.
In order to write a script that is guaranteed to be portable between the various shells, the script must be POSIX Shell compliant. POSIX is a minimum set of builtins and commands that all conforming shells must support. Ash, Dash, Zsh, Bash, Ksh, etc.. are all shells capable of running scripts that are POSIX compliant.
What shells like Bash do is add nice features which make the shell more capable, like additional parameter expansions for conversion to upper/lower case, substring replacement, etc.. and new builtins like [[ ... ]] that provide regex matching capabilities, etc.. While this makes Bash more capable, it also means scripts written using "Bashisms" are no longer able to run under all other shells. Ash, Dash and other minimal shells have no idea how to handle the features added by Bash, Ksh or Zsh and therefore fail.
To write truly portable scripts, you must limit the content to that provided by the POSIX command language.
You need something file like this:
#!/bin/bash #isn't a simple comment
echo "hello bash"
#!/bin/sh #isn't a simple comment
echo "hello sh"
#!/bin/ksh #isn't a simple comment
echo "hello ksh"
( #!) it's called shebang tells the shell what program to interpret the script
called this file as you better prefert (file.bsk), but don't forget give it execute permission it with :
chmod +x file.bsk
then run ./file.bsk
Some commands or utilities are not available in all shells or they might have different behavior in different shell. If you know which command run on which shell or gives you desired output you can write shell specific commends as below
bash -c 'echo bash'
ksh -c 'echo ksh'
All other commands that are common to all shell can be written in normal way.

How to run a tsch script from a bash shell system?

So I have a few tcsh scripts associated with an expensive software that I have to run them on a bash shell system. Is that even possible? This software needs these scripts frequently and is based on tcsh. Is it possible to run 2 shells at the same time? Or just call tcsh shell at the beginning of the script? or is there any compiler to translate the shell scripts? What are my options? Thank you.
Simply put a proper shebang at the top of the script.
Assuming your tcsh is installed as /bin/tcsh, each tcsh script should have this as its first line:
#!/bin/tcsh -f
(The -f tells the shell not to load your startup scripts such as .login or .tcshrc. Any script shouldn't depend on your user environment, so you don't need to invoke your startup scripts -- and it will make your scripts load faster. Note that -f has a different meaning for Bourne-derived shells; use -f only for csh and tcsh scripts.)
If you can't portably assume where tcsh is installed, an alternative is:
#!/usr/bin/env tcsh
But that doesn't let you use the -f option, and it could have other disadvantages; see this answer for details.
Note that there really isn't such a thing as a "bash shell system". Both bash and tcsh are just programs that you can run. One or the other might happen to be the default interactive shell for newly created user accounts, but that doesn't affect being able to run either of them.

Wrong BASH-Variable return from a bash script

I'd like to check the value of $HISTFILE (or any similar BASH-Variable) by a bash script. On the command console 'echo $HISTFILE' is the way I normally go, but from inside a bash script, which only includes:
#!/bin/bash
echo $HISTFILE
gives an empty line instead of showing $HOME/$USER/.bash_history (or similar return values). My questions are:
What is the reason for doing so (since I never had such trouble using bash scripts) and
how can I check the value of BASH-Variables like $HISTFILE from inside a bash script?
Many thanks in advance. Cheers, M.
HISTFILE is only set in interactive shells; scripts run in non-interactive shells. Compare
$ bash -c 'echo $HISTFILE' # non-interactive, no output
$ bash -ic 'echo $HISTFILE' # interactive, produces output
/home/me/.bash_history
However, forcing the script to run in an interactive shell will also cause your .bashrc file to be sourced, which may or may not be desirable.

Set bash script in Eclipse

I have a bash script .sh which needs to be executed as a Target Simulator in Eclipse. The problem is, if I run the script with sh run.sh command in terminal, it throws Bad Substitution error. But it works perfectly with bash run.sh. Apparently, Eclipse run it with sh command cause it gives the same error in console. But how can I make Eclipse to run the script with bash instead?
I'm on Ubuntu 13.10.
bash and sh aren't the same shell. There are many constructs valid in bash that are not understood by sh.
Have you provided a correct sheebang as the first line of your script?
#!/bin/bash
If so -- and if Eclipse insist on running script with sh, you still have the option of wrap your script in a heredoc and pass it to bash explicitly:
sh$ cat run.sh
bash << EOF
#
# Here is your bash script
#
EOF
This is mostly a hack until you find how to instruct Eclipse of using the right shell. I'm sure there is a way!

Bad substitution error in bash script

I have tried a lot but couldn't get the solution out of it. I have a simple script:
#! /bin/sh
o="12345"
a=o
b=${!a}
echo ${a}
echo ${b}
When executed like
$ . scp.sh
it produces the correct output with no errors, but when executed like:
$ ./scp.sh
it produces
./scp.sh: 4: ./scp.sh: Bad substitution
Any ideas why this is happening.
I was suggested to use bash mode and it works fine. But when I execute this same script through Python (changing the script header to bash), I am getting the same error.
I'm calling it from Python as:
import os
os.system(". ./scp.sh")
Try using:
#!/bin/bash
instead of
#! /bin/sh
The reason for this error is that two different shells are used in these cases.
$ . scp.sh command will use the current shell (bash) to execute the script (without forking a sub shell).
$ ./scp.sh command will use the shell specified in that hashbang line of your script. And in your case, it's either sh or dash.
The easiest way out of it is replacing the first line with #!/bin/bash (or whatever path bash is in).

Resources