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

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.

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.

I need to load some modules but load module doesn't work in my environment unless I change the bash profile. How do I do this in tcsh?

. ~/.bashrc is what I'm use to source the bash script in bash shell. But I have quite a few scripts that I want to run from tcsh.But this command doesn't work for tcsh. Why doesn't this work? Is there a different file similar to bash profile when I work on t shell?
Any links to look up?
Thx!
The tcsh equivalent to the bash and posix shell . is source.
That said, bash and tcsh are entirely different shells. You will not be able to source ~/.bashrc from tcsh, if that was your intent.
You can run a shell script of any type as long as that shell script has the appropriate shebang in its first line, but it'll run in its own process, and not in the context of your interactive tcsh instance.
If, for example, you have a directory: ~/.tcshrc.d, and you want to include all the files in that directory in your login shell, you might include the following in your .tcshrc file:
foreach i ( ~/.tcshrc.d/* )
source $i
end
Note that this is tcsh code, and is not compatible with bash.

shell programming difference between #!/bm/bash and #!/bin/sh

Somebody please tell me what's the difference between between #!/bm/bash and #!/bin/sh and links to get better idea please, and why we have to put it at the beggining of a script?
bash and sh are two different shells. Basically bash is sh, with more features and better syntax.
From the bash(1) man page:
If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
You have to put on the first line, to signify that the script should always be run with bash, rather than another shell.
One runs the script in a sh shell and the other runs in a bash shell.
See the Difference between sh and bash.

How to check differences in bash and other shell profiles

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.

Setting Enviroment Variables Dynamically on Linux

I am currently looking for a way to set enviroment variables in Linux via a simple shell script. Within the script I am currently using the 'export' command, however this only has scope within the script where system-wide scope is needed.
Is there anyway I can do this via a shell script, or will another method need to be used?
When you run a shell script, it executes in a sub-shell. What you need is to execute it in the context of the current shell, by sourcing it with:
source myshell.sh
or:
. myshell.sh
The latter is my preferred approach since I'm inherently lazy.
If you're talking about system-wide scope inasmuch as you want to affect everybody, you'll need to put your commands in a place where they're sourced at login time (or shell creation time), /etc/profile for example. Where you put your commands depends on the shell being used.
You can find out what scripts get executed by examining the man page for your shell:
man bash
The bash shell, when invoked as a login shell (including as a non-login shell but with the --login parameter), will use /etc/profile and the first of ~/.bash_profile, ~/.bash_login or ~/.profile.
Non-login bash shells will use. unless invoked with --norc or --rcfile <filename>, the files /etc/bash.bashrc and ~/.bashrc.
I'm pretty certain it's even more convoluted than that depending on how the shell is run, but that's as far as my memory stretches. The man page should detail it all.
You could have your script check for the existence of something like /var/myprog/env-vars-to-load and 'source' it then unlink it if it exists, perhaps using trap and a signal. Its hard to say, I'm not familiar with your program.
There is no way to 'inject' environmental variables into another process' address space, so you'll have to find some method of IPC which will can instruct the process on what to set.
A fundamental aspect of environment variables is that you cannot affect the environment for any process but your own and child processes that you spawn. You can't create a script that sets "system wide" environment variables that somehow become usable by other processes.
On the shell prompt:
$ source script.sh
And set the env vars in script.sh
test.sh
#!/bin/bash
echo "export MY_VAR=STACK_OVERFLOW" >> $HOME/.bashrc
. $HOME/.bashrc
sh task.sh
task.sh
#!/bin/sh
echo $MY_VAR
Add executable rights:
chmod +x test.sh task.sh
And lauch test.sh
./test.sh
Result:
STACK_OVERFLOW

Resources