Linux bash to csh

How to run a csh script from a sh script

I was wondering if there is a way to source a csh script from a sh script. Below is an example of what is trying to be implemented: script1.sh:

#!/bin/csh -f setenv TEST 1234 set path = /home/user/sandbox 

When I run sh script1.sh, I get syntax errors generated from script2 (expected since we are using a different Shebang). Is there a way I can run script2 through script1?

5 Answers 5

Instead of source script2 run it as:

Since your use case depends on retaining environment variables set by the csh script, try adding this to the beginning of script1 :

#!/bin/sh if [ "$csh_executed" -ne 1 ]; then csh_executed=1 exec csh -c "source script2; exec /bin/sh \"$0\" \"\$argv\"" "$@" fi # rest of script1 

If the csh_executed variable is not set to 1 in the environment, run a csh script that sources script2 then executes an instance of sh , which will retain the changes to the environment made in script2 . exec is used to avoid creating new processes for each shell instance, instead just «switching» from one shell to the next. Setting csh_executed in the environment of the csh command ensures that we don’t get stuck in a loop when script1 is re-executed by the csh instance.

Unfortunately, there is one drawback that I don’t think can be fixed, at least not with my limited knowledge of csh : the second invocation of script1 receives all the original arguments as a single string, rather than a sequence of distinct arguments.

You don’t want source there; it runs the given script inside your existing shell, without spawning a subprocess. Obviously, your sh process can’t run something like that which isn’t a sh script.

Just call the script directly, assuming it is executable:

The closest you can come to sourcing a script with a different executor than your original script is to use exec . exec will replace the running process space with the new process. Unlike source , however, when your exec -ed program ends, the entire process ends. So you can do this:

#!/bin/sh exec /path/to/csh/script 
#!/bin/sh exec /path/to/csh/script some-other-command 

However, are you sure you really want to source the script? Maybe you just want to run it in a subprocess:

#!/bin/sh csh -f /path/to/csh/script some-other-command 

Thank you for the informative answer. After reading your answer I see that I meant to run it as a subprocess. Forgive my haste but I am still getting use to posting.

You want the settings in your csh script to apply to the sh script that invokes it.

Basically, you can’t do that, though there are some (rather ugly) ways you could make it work. If you execute your csh script, it will set those variables in the context of the process running the script; they’ll vanish as soon as it returns to the caller.

Your best bet is simply to write a new version of your csh script as an sh script, and source or . it from the calling sh script.

Читайте также:  Готовый linux образ для флешки

You could translate your csh script:

#!/bin/csh -f setenv TEST 1234 set path = /home/user/sandbox 
export TEST=1234 export PATH=/home/user/sandbox 

(csh treats the shell array variable $path specially, tying it to the environment variable $PATH . sh and its derivatives don’t do that, they deal with $PATH itself directly.)

Note that a script intended to be sourced should not have a #! line at the top, since it doesn’t make sense to execute it in its own process; you need to execute its contents in the context of the caller.

If maintaining two copies of the script, one to be source d from csh or tcsh scripts and another to be source d or . ed from sh/ksh/bash/zsh script, is not practical, there are other solutions. For example, your script can print a series of sh commands to be executed; you can then do something like

(line endings will pose some issues here).

Or you can modify the csh script so it sets the required environment variables and then invokes some specified command, which could be a new interactive shell; this is inconvenient, since it doesn’t set those variables in the interactive shell you’re running.

If a software package requires some special environment variables to be set, it’s common practice to provide scripts called, for example, setup.sh and setup.csh , so that sh/ksh/bash/zsh users can do:

source /path/to/package/setup.csh 

Incidentally, this command:

set path = /home/user/sandbox 

in your sample script is probably not a good idea. It replaces your entire $PATH with just a single directory, which means you won’t be able to execute simple commands like ls unless you specify their full paths. You’d usually want something like:

set path = ( $path /home/user/sandbox ) 

Источник

Change shell from bash to csh

right now when i’m executing the csh from within the bash, the variables inside the subshell of the bash are left unchanged. example: in this example I would to see that the PATH variable is changed after running the csh script (it is one of the results) would appreciate any thoughts. Question: I am currently converting a csh script on linux to a bash script on Mac OS X lion.

Running csh script from bash script

I am writing a script that requires a initial setup. the setup is in the form of csh script that has many artifacts on the environment variables. right now when i’m executing the csh from within the bash, the variables inside the subshell of the bash are left unchanged.

#!/bin/bash echo $PATH setevnvar.csh -dir $ROOT_DIR/ echo $PATH 

in this example I would to see that the PATH variable is changed after running the csh script (it is one of the results)

would appreciate any thoughts.

It is not possible to modify the variables of a shell from any child process . Since launching csh from bash launches a child process, there is no way that can be done.

  • Convert your csh script to bash , and source it from your bash script.
  • Convert your bash script to csh , and again source the other script
  • Make sure the variables you need are marked for export in the csh script, and launch your bash script from inside the csh script (which may or may not work for your specific need), thereby turning things inside out
  • Merge the code from both scripts to have a single ( bash or csh ) script
Читайте также:  Linux btrfs file system

«Sourcing» is done with a . or the (non-POSIX) source builtin. For instance :

#!/bin/bash echo $PATH . setevnvar.converted_to_bash -dir "$ROOT_DIR/" echo $PATH 

«Sourcing» causes the current process to read commands from an other file and execute them as if they were part of the current script, rather than starting a new shell to execute that other file. This is why variable assignments will work with this method.

Please note I added double quotes to your «$ROOT_DIR/» expansion, to protect for the case where it would contain special characters, like spaces.

Linux — Switching from bash to csh prompt, Make sure you’ve got csh installed. 2.Learn the location of csh: which csh or whereis csh. Below, I’ll assume the location is /bin/bash. a) If you …

How to switch from Bash to C Shell on Linux

C Shell is a command -line shell for Unix that uses a C++ syntax, rather than the familiar Bash syntax. It’s an older shell , but loved in the Unix community b

How to convert a bash script to tcsh

function history_to_syslog < declare command remoteaddr="`who am i`" pwd="`pwd`" command=$(fc -ln -0) if [ "$command" != "$old_command" ]; then logger -p local2.notice -t bash -i ? "$USER : $remoteaddr" \ "Command : $command Directory : $pwd" fi old_command=$command >trap history_to_syslog DEBUG 

How do I change to change the bash scripts to tcsh?

To change a script from bash to csh, you first need to learn about the differences between the different shell environments. For example study this guide on http://hyperpolyglot.org. You might learn, that the vast majority is equivalent. Some syntax can directly be translated into each other. However, some syntax is too specific to its shell to be directly translatable.

Your next step is to identify which parts of your code can be translated directly, and which parts do not have a 1-to-1 translation — and therefore need another implementation csh.

How to change Bash to csh with username and password, The reason this command is failing is because you are providing too many parameters. chsh does not accept a password on the command line, and if you …

Convert csh script to bash script

I am currently converting a csh script on linux to a bash script on Mac OS X lion.

The csh script looks like:

setenv CNS_SOLVE '/Users/ucbthsa/Documents/haddock2.1/software/bin/' setenv CNS_SOLVE $CNS_SOLVE if ( -d $CNS_SOLVE ) then if ( ! $?CNS_ARCH ) setenv CNS_ARCH `$CNS_SOLVE/bin/getarch` else setenv CNS_ARCH 'unknown' endif 

My conversion to a Mac bash script looks as follows:

export CNS_SOLVE='/Users/ucbthsa/Documents/haddock2.1/software/bin/cns_solve_1.3' export CNS_SOLVE=$CNS_SOLVE if [ -d $CNS_SOLVE ]; then if [ ! $?CNS_ARCH ]; then export CNS_ARCH='$CNS_SOLVE/bin/getarch' else export CNS_ARCH='unknown' endif 

When I try and source the Mac bash script I get the following error:

-bash: cns_solve_env: line 10: syntax error: unexpected end of file

I cannot understand why I am getting this error.

You should use fi rather than endif and you aren’t closing the first if at all:

export CNS_SOLVE='/Users/ucbthsa/Documents/haddock2.1/software/bin/cns_solve_1.3' export CNS_SOLVE=$CNS_SOLVE if [ -d $CNS_SOLVE ]; then if [ -z $CNS_ARCH ]; then export CNS_ARCH="$CNS_SOLVE/bin/getarch" fi else export CNS_ARCH='unknown' fi 

*edit: changed the second test, as William Pursell pointed out, it wouldn’t work as it was in bash.

Читайте также:  Создать файл сокета linux

$?CNS_ARCH means something different in sh. Use:

test -z "$CNS_ARCH" && CNS_ARCH=$($CNS_SOLVE/bin/getarch) 

Notice that these have slightly different meanings. The first is will assign to CNS_ARCH if CNS_ARCH is already set but is the empty string, while the second will not change CNS_ARCH if it is already set, but is empty, which is what the $? does in csh, but is probably not what you actually want.

Run csh scripts from bash, change shell temporary via, I need to run csh scripts from a bash shell and therefore temporary change to tcsh via a command. It works perfect in interactive mode …

Источник

how to source csh script from bash environment?

I am using bash shell but some of the scripts that I need to source are in csh format. Can somebody tell how I can source csh scripts from bash shell? By sourcing I mean the sourced csh script should be able to set the environment variables. So, I want to do something like this in my ~/.bashrc :

source path/to/csh_script/script.cshrc 

@Serg One could use a lot of things. But it maybe that there are csh features that have no bash equivalents. I don’t know. Good luck writing a csh to bash compiler in awk.

3 Answers 3

bash won’t run all csh scripts perfectly. There may be some basic overlap, like very basic bash scripts will run in sh/dash, but if it fails to run in bash (test with bash [file] ) then it’s a no-go. Either

  • modify them to run in bash, or
  • run them with csh, called from the bash script, as if you’re running them in a terminal, having them return a result value or do whatever they’re supposed to. This would not leave any variables or functions available to the main bash script, as you’ve commented, so you’ll either
    • have them do whatever they’re supposed to do to external files, or
    • return a single value/string, or maybe
    • treat them like another program and read multiple lines of output into your bash script.

    If you’re just looking to source variables, it’s theoretically possible to go through the csh script line-by-line and adding just the variables into the current bash shell/script. Something similar to this:

    while read line do [stuff with $line] done < /path/to/[the csh script to add] 

    I don't know how all the variables are laid out in the scripts you're sourcing, so it's up to you to decide what the [stuff with $line] should be.

    • If they're like bash, then maybe just grep any lines that begin with spaces or characters, have a = with optionally more characters with no spaces, so: echo "$line" | grep '^\s*\S*=\S*'
    • or as above with anything after the = with: echo "$line" | grep '^\s*\S*=.*'

    But I think csh variables all start with set / setenv , so could find set/setenv lines, then throw out the set/setenv. Try as a starter:

    Those're just quick sample grep / regex patterns, see this & that & others for more info.

    Or, if it's only a few of them, go through them manually & paste all the variables into bash/sh compatible files you can then source in bash with no problems.

    Источник

Оцените статью
Adblock
detector