presmerovani vystupu v bashi

Alexandr Malusek malusek na hroch.ujf.cas.cz
Pondělí Červenec 27 20:53:18 CEST 1998


adelton na informatics.muni.cz (Honza Pazdziora) writes:

> 	exec > out
> 	echo To out
> 	exec > /dev/tty
> 	echo To tty
> 
> dava vcelku uspokojive vysledky.

Dalsi moznosti je presmerovat nejaky volny file descriptor na soucasne
stdout, a pak v pripade potreby presmerovat stdout na tento FD:

#!/bin/bash
exec 4>&1     # predpoklada se, ze FD 4 neni pouzivan
exec >eee
echo Jedna
exec >iii
echo Dve
exec 1>&4     # nastavi FD 1 (stdout) na puvodni nastaveni
echo Tri
exit

Na rozdil od predchoziho reseni s tty se zachova presmerovani, i kdyz
je skript spusten s presmerovanym stdout.

Seznam pouzitych FD lze na Linuxu zjistit v adresari /proc/<PID>/fd.
Volny FD bych ale takto nehledal - zda se mi to prilis
neprenositelne. Spis bych si napsal program jako napr.:

$ cat ffd.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main()
{
  int fd;
  if ((fd = open("/etc/passwd", O_RDONLY)) == -1)
    {
      perror("ffd: Nemohu otevrit /etc/passwd");
      return -1;
    }
  close(fd);
  return fd;
}

ktery jako exit kod vraci prvni volny FD. (Vysvetleni: program ffd
zdedi file descriptory od skriptu, ktery jej spousti. Systemove volani
open() nalezne nejnizsi volny deskriptor pro ffd, tedy i pro puvodni
skript). Pouzit se to pak da takto:

#!/bin/bash
./ffd
FFD=$?                   # $? obsahuje exit kod
eval "exec ${FFD}>&1"    # bez eval je ${FFD} interp. jako jm. prikazu
exec >eee
echo Jedna
exec >iii
echo Dve
exec 1>&${FFD}
echo Tri
exit

Take bych zvazil, zda neni vhodnejsi pouzit bloky:

#!/bin/bash
{
  echo Jedna
} > eee

{
  echo Dve
} > iii

echo Tri
exit

--
A. Malusek  (malusek na ujf.cas.cz)
UJF AV CR


Další informace o konferenci Linux