finalidade do utilitário run-parts (8)

5

Pelo menos em sistemas baseados em Debian, existe um utilitário run-parts no pacote debianutils que é usado em vários scripts. Por exemplo, em / etc / X11 / Xsession. Ele irá executar todos os arquivos executáveis encontrados em um diretório. Por que as peças de execução são necessárias enquanto é possível usar find com -perm option ou test utility? Além disso, o que run-parts considera como um arquivo executável? Parece que não basta verificar as permissões do arquivo:

# run-parts --list --lsbsysinit /etc/X11/Xsession.d | tail -1
/etc/X11/Xsession.d/90x11-common_ssh-agent
# ls -l /etc/X11/Xsession.d/90x11-common_ssh-agent
-rw-r--r-- 1 root root 629 2010-11-02 23:17 /etc/X11/Xsession.d/90x11-common_ssh-agent
# head /etc/X11/Xsession.d/90x11-common_ssh-agent
# $Id: 90x11-common_ssh-agent 305 2005-07-03 18:51:43Z dnusinow $

# This file is sourced by Xsession(5), not executed.

STARTSSH=
SSHAGENT=/usr/bin/ssh-agent
SSHAGENTARGS=

if has_option use-ssh-agent; then
  if [ -x "$SSHAGENT" ] && [ -z "$SSH_AUTH_SOCK" ] \
# 
    
por Martin 24.03.2014 / 17:13

3 respostas

7

Você pode usar find em vez de run-parts , não é possível mostrar qual é o melhor. Mas acho que usar run-parts é mais curto (menos digitação) e tornar seu script mais sustentável. Um exemplo é /etc/crontab :

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the 'crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Para a segunda pergunta, você pode encontrar a resposta no código-fonte debianutils . No arquivo run-parts.c , linha 198:

/* Execute a file */                                                            
void run_part(char *progname)                                                   
{ 
     ....
     args[0] = progname;                                                         
     execv(progname, args);                                                      
     error("failed to exec %s: %s", progname, strerror(errno));                  
     exit(1);
     ....
}

Você pode ver run-parts usando execv chamada do sistema. Portanto, se seu arquivo não for um binário executável ou um Interpreter script , execv não poderá executar o arquivo.

Nota

  • O que é Interpreter script :

De man execve , seção Interpreter scripts :

Interpreter scripts
       An  interpreter  script  is  a  text  file  that has execute permission
       enabled and whose first line is of the form:

           #! interpreter [optional-arg]

       The interpreter must be a valid pathname for an executable which is not
       itself  a  script.   If  the filename argument of execve() specifies an
       interpreter script, then interpreter will be invoked with the following
       arguments:

           interpreter [optional-arg] filename arg...

       where arg...  is the series of words pointed to by the argv argument of
       execve().

       For portable use, optional-arg should either be absent, or be specified
       as  a  single word (i.e., it should not contain white space); see NOTES
       below.
  • Você pode ver o código fonte do debianutils aqui .
por 24.03.2014 / 17:56
2

Os arquivos que run-parts são executados estão bem documentados. Além de serem executáveis, o seguinte snippet de página de manual explica os requisitos:

If  neither  the --lsbsysinit option nor the --regex option is given then the
names must consist entirely of ASCII upper- and lower-case letters, ASCII digits,
ASCII underscores, and ASCII minus-hyphens.

If the --lsbsysinit option is given, then the names must not end in .dpkg-old  or
.dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong to one or more  of  the 
following  namespaces:  the  LANANA-assigned  namespace  (^[a-z0-9]+$); the LSB
hierarchical and reserved namespaces (^_?([a-z0-9_.]+-)+[a-z0-9]+$); and the
Debian cron script namespace (^[a-zA-Z0-9_-]+$)

Usar a opção --lsbsysinit é particularmente útil para executar scripts em /etc , pois muitos dos scripts serão listados como arquivos de configuração em seus respectivos pacotes. Um caso comum em que arquivos com a extensão dpkg-* são criados é quando as alterações foram feitas na versão instalada e dpkg tenta instalar uma nova versão. dpkg geralmente armazena a versão que o usuário não escolheu no mesmo diretório. Usar run-parts é uma maneira padrão e boa de garantir que nenhuma dessas extensões ou quaisquer outras que não sejam feitas para serem executadas não sejam. Isso reduz as chances de insetos aparecerem porque um desenvolvedor esqueceu de incluir um deles em seu script.

Mesmo sem o --lsbsysinit , ainda é um comando útil para reduzir a quantidade de código que precisa ser escrita e melhorar a confiabilidade quando usado em todo o sistema. Embora não seja tanto quanto é mais fácil substituir por um find ... -executable -exec {} ; ou algo parecido.

    
por 24.03.2014 / 19:35
1
Why is run-parts needed while one could use find 
with -perm option or test utility?

Isso é simplesmente por design. Como você pode ver na página do manual, run-parts também possui várias opções. Todas as coisas também podem ser escritas em shell.

[Editar]

Também é provável que tenha sido implementado em C para evitar hackers.

    
por 24.03.2014 / 17:40