2016-04-13 8 views
2

Ich habe UNIX- und Systemaufrufe studiert und stieß dabei auf knifflige und knifflige Fragen. Die Frage stellt, was Systemaufrufe für diesen Befehl aufgerufen werden:Implizite Systemaufrufe in UNIX-Befehlen

grep word1 word2 > file.txt

Ich habe einige Nachforschungen und ich war nicht in der Lage eine große Anzahl von Ressourcen auf dem zugrunde liegenden UNIX ruft zu finden. Allerdings scheint es mir, dass die Antwort wäre open (zu öffnen und die Dateideskriptor für die Datei file.txt), dann dup2 (um die STDOUT von grep an den Dateideskriptor open zu ändern), dann write die STDOUT von grep zu schreiben (das ist jetzt der Dateideskriptor file.txt), und schließlich close(), um den Dateideskriptor file.txt zu schließen ... Allerdings habe ich keine Ahnung, ob ich richtig oder auf dem richtigen Pfad bin, kann jemand mit Erfahrung in UNIX mich aufklären dieses Thema?

+1

Ich hoffe, dass Sie die Antwort auf Ihre Frage finden hier , aber Sie können [diesen Stapel] (http://unix.stackexchange.com/) besser finden, um es zu beantworten. Viel Glück! – Vandal

+0

Sie können sich den [Quellcode von GNU grep] (http://git.savannah.gnu.org/cgit/grep.git) ansehen. –

+3

"STDOUT" Umleitung wird von der Shell durchgeführt, 'grep' weiß nicht einmal, dass eine Umleitung stattfindet, das ist völlig transparent. –

Antwort

5

Sie haben die richtige Richtung in Ihrer Forschung. Dieser Befehl ist sehr hilfreich Systemaufrufe in jedem Programm zu verfolgen:

strace

Auf meinem PC es zeigt Ausgang (ohne Strom Umleitung):

$ strace grep abc ss.txt 
execve("/bin/grep", ["grep", "abc", "ss.txt"], [/* 237 vars */]) = 0 
brk(0)         = 0x13de000 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1785694000 
close(3)        = 0 
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 
stat("ss.txt", {st_mode=S_IFREG|0644, st_size=13, ...}) = 0 
open("ss.txt", O_RDONLY)    = 3 
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fffa0e4f370) = -1 ENOTTY (Inappropriate ioctl for device) 
read(3, "abc\n123\n321\n\n", 32768)  = 13 
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f178568c000 
write(1, "abc\n", 4abc 
)     = 4 
read(3, "", 32768)      = 0 
close(3)        = 0 
close(1)        = 0 
munmap(0x7f178568c000, 4096)   = 0 
close(2)        = 0 
exit_group(0)       = ? 
+1

Aber das ist ein Linux-spezifisches Tool. Für Unix im Allgemeinen können Sie normalerweise 'dtrace' verwenden. (Was ich denke, wird bald auch auf Linux portiert werden.) –

+3

@DavidOngaro: Die Behauptung, 'dtrace' sei normal für Unix, wäre eine Übertreibung, denke ich. Sie können "dtrace" unter Solaris verwenden (obwohl "truss" für den Benutzer einfacher ist); Eine Variante von 'dtrace' existiert auf Mac; aber andere Systeme (HP-UX, AIX, ...) benutzen andere Befehle (als 'dtrace' oder' strace' oder 'truss'). –