Cómo ejecutar un script csh desde un script sh
Frecuentes
Visto 46,414 veces
5
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/sh
source script2
script2:
#!/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 Respuestas
6
En lugar de source script2
ejecutarlo como:
csh -f script2
Respondido el 28 de enero de 14 a las 18:01
2
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
Si 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
en el entorno de la csh
command ensures that we don't get stuck in a loop when script1
is re-executed by the csh
ejemplo.
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.
Respondido el 28 de enero de 14 a las 19:01
1
No quieres 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:
script2
Respondido el 28 de enero de 14 a las 18:01
1
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
pero no puedes hacer esto:
#!/bin/sh
exec /path/to/csh/script
some-other-command
However, are you sure you really want to fuente the script? Maybe you just want to run it in a subprocess:
#!/bin/sh
csh -f /path/to/csh/script
some-other-command
Respondido el 28 de enero de 14 a las 18:01
0
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 ejecutar 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 y source
or .
it from the calling sh script.
You could translate your csh script:
#!/bin/csh -f
setenv TEST 1234
set path = /home/user/sandbox
a esto:
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 no tiene un #!
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
do .
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
eval `./foo.csh`
(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
y setup.csh
, so that sh/ksh/bash/zsh users can do:
. /path/to/package/setup.sh
and csh/tcsh 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 reemplaza tu entero $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 )
or, in sh:
PATH=$PATH:/home/user/sandbox
Respondido el 28 de enero de 14 a las 19:01
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas linux bash shell csh or haz tu propia pregunta.
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. - user3245776