GNU/Linux >> Znalost Linux >  >> Linux

Jak získat další informace o původu výstupního kódu?

Někdy potřebuji udržovat programy, které vyvolávají skripty shellu, které spouštějí jiné programy a skripty. Proto, když hlavní skript shellu končí ukončovacím kódem 126, je těžké zjistit, které z vyvolaných skriptů a příkazů nastavují tento ukončovací kód.

Existuje způsob, jak zjistit, který příkaz byl důvodem pro návratový kód, aby bylo snazší zkontrolovat jeho oprávnění?

Přijatá odpověď:

Pokud používáte Linux, můžete spustit příkaz pod strace -fe process zjistit, který proces provedl exit_group(126) a jaký příkaz (nebo kterýkoli z jeho nadřazených příkazů, pokud sám nic neprovedl) provedl naposledy před tím:

$ strace -fe process sh -c 'env sh -c /; exit'
execve("/bin/sh", ["sh", "-c", "env sh -c /; exit"], [/* 53 vars */]) = 0
arch_prctl(ARCH_SET_FS, 0x7f24713b1700) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24713b19d0) = 26325
strace: Process 26325 attached
[pid 26324] wait4(-1,  <unfinished ...>
[pid 26325] execve("/usr/bin/env", ["env", "sh", "-c", "/"], [/* 53 vars */]) = 0
[pid 26325] arch_prctl(ARCH_SET_FS, 0x7fbdb4e2c700) = 0
[pid 26325] execve("/bin/sh", ["sh", "-c", "/"], [/* 53 vars */]) = 0
[pid 26325] arch_prctl(ARCH_SET_FS, 0x7fef90b3b700) = 0
[pid 26325] clone(strace: Process 26326 attached
child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fef90b3b9d0) = 26326
[pid 26325] wait4(-1,  <unfinished ...>
[pid 26326] execve("/", ["/"], [/* 53 vars */]) = -1 EACCES (Permission denied)
sh: 1: /: Permission denied
[pid 26326] exit_group(126)             = ?
[pid 26326] +++ exited with 126 +++
[pid 26325] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 126}], 0, NULL) = 26326
[pid 26325] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26326, si_uid=10031, si_status=126, si_utime=0, si_stime=0} ---
[pid 26325] exit_group(126)             = ?
[pid 26325] +++ exited with 126 +++
<... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 126}], 0, NULL) = 26325
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=26325, si_uid=10031, si_status=126, si_utime=0, si_stime=0} ---
exit_group(126)                         = ?
+++ exited with 126 +++

Výše to byl proces 26326, který nejprve skončil s 126, protože se pokusil provést / . Byl to potomek procesu 26325, který naposledy provedl sh -c / .

Pokud jsou tyto skripty bash skripty nebo pokud jsou sh skripty a sh je náhodou bash ve vašem systému můžete provést:

$ env SHELLOPTS=xtrace 
      BASH_XTRACEFD=7 7>&2 
      PS4='[$?][$BASHPID|${BASH_SOURCE:-$BASH_EXECUTION_STRING}|$LINENO]+ '  
    sh -c 'env sh -c /; exit'
[0][30625|env sh -c /; exit|0]+ env sh -c /
[0][30626|/|0]+ /
sh: /: Is a directory
[126][30625|env sh -c /; exit|0]+ exit

To nám přesně neříká, jaký proces byl ukončen pomocí 126, ale mohlo by vám to poskytnout dostatečné vodítko.

Související:Jak přejmenovat více souborů pomocí find?

Používáme BASH_TRACEFD=7 7>&2 tak, aby se stopy dostaly na originál stderr, i když je stderr přesměrován ve skriptech. Jinak by tyto sledovací zprávy mohly ovlivnit chování skriptů, pokud provádějí věci jako (....) 2>&1 | ... . To předpokládá, že tyto skripty samy explicitně nepoužívají nebo neuzavírají fd 7 (to by bylo nepravděpodobné, mnohem nepravděpodobnější než přesměrování stderr).


Linux
  1. Jak vyhledat výstupní kódy pro aplikace?

  2. Jak získat klíč USB k automatickému připojení?

  3. Nedaří se vám získat správný výstupní kód ze skriptu?

  1. Jak získat informace o kontejneru v Dockeru

  2. Jak rozebrat binární spustitelný soubor v Linuxu, abyste získali kód sestavení?

  3. Jak získat stav ukončení smyčky v bash

  1. Jak bezpečně získat verzi Ksh?

  2. Jak získat výstupní kód vytvořeného procesu ve skriptu očekávaného shellu?

  3. Jak zjistit podrobnosti o hardwaru na počítači se systémem Linux?