web-dev-qa-db-fra.com

Rediriger stderr vers stdout dans le shell C

Lorsque j'exécute la commande suivante dans csh, je n'ai rien, mais cela fonctionne dans bash, existe-t-il un équivalent dans csh qui peut rediriger l'erreur standard vers la sortie standard?

somecommand 2>&1
57
zdd

Le shell csh n'a jamais été reconnu pour sa capacité à manipuler les descripteurs de fichiers dans le processus de redirection.

Vous pouvez rediriger à la fois la sortie standard et l’erreur sur un fichier avec:

xxx >& filename

mais ce n'est pas tout à fait ce que vous recherchiez: rediriger l'erreur standard vers la sortie standard actuelle.


Cependant, si votre système d'exploitation sous-jacent expose la sortie standard d'un processus dans le système de fichiers (comme le fait Linux avec /dev/stdout), vous pouvez utiliser cette méthode comme suit:

xxx >& /dev/stdout

Cela forcera la sortie standard et erreur standard à se placer au même endroit que la sortie standard actuelle, ce que vous avez avec la redirection bash, 2>&1.

Gardez simplement à l'esprit que ce n'est pas une fonctionnalité csh. Si vous utilisez un système d'exploitation qui ne le fait pas expose la sortie standard sous forme de fichier, vous ne pouvez pas utiliser cette méthode.


Cependant, il existe une autre méthode. Vous pouvez combiner les deux flux en un seul si vous l'envoyez à un pipeline avec |&, il vous suffit alors de trouver un composant de pipeline qui écrit son entrée standard sur sa sortie standard. Au cas où vous ne le sauriez pas, c'est exactement ce que cat fait si vous ne lui donnez aucun argument. Par conséquent, vous pouvez atteindre vos objectifs dans ce cas spécifique avec:

xxx |& cat

Bien sûr, rien ne vous empêche également d’exécuter bash (en supposant qu’il se trouve quelque part sur le système) au sein de un script csh pour vous donner les fonctionnalités supplémentaires. Vous pouvez ensuite utiliser les redirections riches de ce shell pour les cas plus complexes où csh peut rencontrer des difficultés.

Explorons cela plus en détail. Tout d’abord, créez un exécutable echo_err qui écrira une chaîne dans stderr:

#include <stdio.h>
int main (int argc, char *argv[]) {
    fprintf (stderr, "stderr (%s)\n", (argc > 1) ? argv[1] : "?");
    return 0;
}

Puis un script de contrôle test.csh qui va le montrer en action:

#!/usr/bin/csh

ps -ef ; echo ; echo $$ ; echo

echo 'stdout (csh)'
./echo_err csh

bash -c "( echo 'stdout (bash)' ; ./echo_err bash ) 2>&1"

Les echo du PID et ps servent simplement à vous assurer que csh exécute ce script. Lorsque vous exécutez ce script avec:

./test.csh >test.out 2>test.err

(la redirection initiale est configurée par bashavantcsh commence à exécuter le script) et examinez le fichier out/err fichiers, vous voyez:

test.out:
    UID     PID    PPID  TTY        STIME     COMMAND
    pax    5708    5364  cons0      11:31:14  /usr/bin/ps
    pax    5364    7364  cons0      11:31:13  /usr/bin/tcsh
    pax    7364       1  cons0      10:44:30  /usr/bin/bash

    5364

    stdout (csh)
    stdout (bash)
    stderr (bash)

test.err:
    stderr (csh)

Vous pouvez voir que le test.csh processus est en cours d'exécution dans le shell C, et l'appel de bash à partir de là vous donne le plein bash pouvoir de redirection.

Le 2>&1 dans la commande bash vous permet assez facilement de rediriger l'erreur standard vers la sortie standard actuelle (comme vous le souhaitez) sans connaître au préalable l'emplacement actuel de la sortie standard.

75
paxdiablo

Je m'oppose à la réponse ci-dessus et je fournis la mienne. csh a cette capacité et voici comment procéder:

xxx |& some_exec # will pipe merged output to your some_exec 

ou

xxx |& cat > filename

ou si vous voulez juste qu'il fusionne les flux (vers stdout) et ne redirige pas vers un fichier ou une_exec:

xxx |& tee /dev/null
42
bioffe

Comme l'a dit paxdiablo, vous pouvez utiliser >& pour rediriger stdout et stderr. Toutefois, si vous souhaitez les séparer, vous pouvez utiliser les éléments suivants:

(command > stdoutfile) >& stderrfile

... comme indiqué ci-dessus redirige stdout vers stdoutfile et stderr vers stderrfile.

35
Chris

Qu'en est-il juste

xxx >& /dev/stdout

???

4
ChPortos
   xxx >& filename

Ou faites ceci pour tout voir à l'écran et le faire aller dans votre fichier:

  xxx | & tee ./logfile
4
Ryan P