[bash] redirect stderr naar een variable

Pagina: 1
Acties:

  • Sir Isaac
  • Registratie: September 2002
  • Laatst online: 21-05-2025
stdout kun je heel makkelijk in een variabele zetten (var=$(commando) ). Hoe doe je dit met stderr? Je kunt natuurlijk stderr redirecten naar stdout, maar dat is niet erg elegant.
Ik wil namelijk in bash iets kunnen doen met de stderr van een commando (mkdir).

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Ik zie niet wat er niet elegant is aan redirecten naar stdout? En als je dat echt niet wilt dan kan je natuurlijk lekker omslachtig gaan doen door stderr naar een file te schrijven en deze weer in te lezen :)
Maar ik zou gewoon strerr redirecten naar stdout, afaik geeft mkdir toch geen feedback naar stdout, dus maakt dat ook niks uit :)

  • Sjonny
  • Registratie: Maart 2001
  • Laatst online: 19:54

Sjonny

Fratser

Sir Isaac schreef op woensdag 12 april 2006 @ 23:41:
Ik wil namelijk in bash iets kunnen doen met de stderr van een commando (mkdir).
ik kan me niet indenken waarom je dit wil. Wanneer je een andere taal gebruikt, krijg je de error melding van mkdir ook in die taal. Je kan beter de '-p' optie gebruiken, en dan testen op de return code in $?.

The problem is in the part of your brain that handles intelligence.


  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 00:42
stderr kan je met 2>&1 redirecten naar stdout:

mkdir /een/directory/met/fout > /dev/null 2>&1

hierbij wordt stdout naar /dev/null gegooid en stderr naar stdout.

Verwijderd

Jij zoekt dit:
code:
1
var=$(commando 2>&1 >&-)

Voorbeeld:
code:
1
2
3
4
5
6
7
$ var=$(mkdir xxx 2>&1 >&-)
$ echo $var

$ var=$(mkdir xxx 2>&1 >&-)
$ echo $var
mkdir: cannot create directory `xxx': File exists
$

Dus eerst stderr duplicaten als stdout en daarna de oorspronkelijke stdout dichtgooien. Je ziet het nog beter als je 'mkdir -v' gebruikt. Normaal gesproken zie je dan de aanmaakacties in stdout verschijnen, maar met de constructie 2>&1 >&- zijn die verdwenen. Alleen foutmeldingen komen in $var terecht, ongeacht wat er door mkdir naar stdout wordt gestuurd.

>&- en >/dev/null hebben het zelfde effect: je bent stdout kwijt. Strikt genomen is het niet identiek: de eerste constructie gooit het kanaal dicht, de tweede blijft open en stuurt de info door naar /dev/null; dat je het nooit meer ziet is een ander verhaal natuurlijk.

Dit klopt niet:
_JGC_ schreef op donderdag 13 april 2006 @ 01:21:
stderr kan je met 2>&1 redirecten naar stdout:

mkdir /een/directory/met/fout > /dev/null 2>&1

hierbij wordt stdout naar /dev/null gegooid en stderr naar stdout.
Je bedoelt waarschijnlijk hetzelfde, alleen is het verkeerd om... je stuurt eerst de originele stdout naar een zwart gat en vervolgens stderr naar de plek waar op dat moment stdout naar staat te wijzen, dus ook naar het zwarte gat. De volgorde is belangrijk!
Andersom, met '2>&1 >/dev/null' gaat het wel goed: stderr wordt gedupliceerd als stdout (hij opent ahw een 2e stdout-kanaal), daar gaat stderr vanaf dat moment heen. Daarna kan je de oorspronkelijke stdout weggooien met >/dev/null.

[ Voor 45% gewijzigd door Verwijderd op 13-04-2006 18:37 ]


  • blaataaps
  • Registratie: Juli 2001
  • Niet online
_JGC_ schreef op donderdag 13 april 2006 @ 01:21:
stderr kan je met 2>&1 redirecten naar stdout:

mkdir /een/directory/met/fout > /dev/null 2>&1

hierbij wordt stdout naar /dev/null gegooid en stderr naar stdout.
Ja en nee. Ja stderr gaat naar stdout, maar stdout is niet "de terminal" of "de pipe waar je toevallig aanhangt". Op deze manier eindigt alle output in /dev/null, sowieso is de benaming "naar stdout" een beetje ambigu gebruikt in je post.
Je wil het andersom, 2>&1 >/dev/null. stderr gaat dan naar de 'reguliere' output, en stdout naar /dev/null.

  • xzenor
  • Registratie: Maart 2001
  • Laatst online: 14-10-2022

xzenor

Ja doe maar. 1 klontje suiker.

code:
1
2
COMMANDO="mkdir /blabla"
var=$($COMMANDO 2>&1)

of korter
code:
1
var=$(mkdir /blablabl 2>&1)


In beide gevallen heeft variable $var de output van het commando, of dit nou stderr is of niet. met 2>&1 redirect je stderr naar stdout zoals al eerder vermeld.

Wil je 'alleen' stderr hebben, dan is het wat moeilijker, dan moet je namelijk stderr en stdout om zien te keren.

code:
1
2
COMMAND="ls -al"
var=$(($COMMAND>/dev/null) 3>&1 1>&2 2>&3 )


zie hier de output er van:
code:
1
2
3
4
5
$ COMMAND="ls -al"
$ var=$(($COMMAND>/dev/null) 3>&1 1>&2 2>&3 )
$ echo $var

$


En bij een fout:
code:
1
2
3
4
5
$ COMMAND="ls b"
$ var=$(($COMMAND>/dev/null) 3>&1 1>&2 2>&3 )
$ echo $var
ls: b: No such file or directory
$


Ik neem aan dat je hier wel wat aan hebt :)
Laat nog even weten of het allemaal gelukt is.
Pagina: 1