Script para percorrer as pastas $ PATH e ver quais arquivos executáveis estão disponíveis em seu sistema

1

Aqui está o que eu tenho até agora:

#!/bin/bash

for file in $PATH ; do # Scanning files in $PATH

        if [ -x ] ; then #Check if executable
                echo "Executable File"
        else
                echo "Not executable"
        fi
done

A saída é "O arquivo é executável"

Não acho que esteja circulando corretamente em todas as pastas

    
por Tyler 07.04.2017 / 01:40

5 respostas

6

Por um lado, $PATH fornece uma lista de diretórios. Se você quiser verificar cada arquivo no seu $PATH , precisará examinar cada arquivo em cada diretório, não apenas verificar cada item em $PATH .

Em seguida, você está usando -x para ver se o arquivo é executável, mas não está especificando qual arquivo verificar. Eu escrevi uma versão alterada abaixo:

IFS=':'
for directory in $PATH; do
    for file in $directory/*; do
        if [ -x $file ]; then
            echo "Executable File: " $file
        else
            echo "Not executable: " $file
        fi
    done
done

A resposta da Fox é uma solução muito melhor, mas eu achei que você estaria interessada no que havia de errado com a sua.

    
por 07.04.2017 / 02:00
6

Se o que você deseja é uma lista de arquivos executáveis, find é suficiente:

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')'

Isso listará o caminho completo de todos os executáveis no seu $PATH . O IFS=':' garante que $PATH seja dividido em dois pontos ( : ), o separador para essa variável.

Se você não quer o caminho completo , mas apenas os nomes dos executáveis , você pode fazer

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' -exec basename {} \; | sort

Se o seu find é compatível com GNU, a condição simplifica bastante:

IFS=':'
find $PATH -type f -executable -exec basename {} \; | sort

Como aponta o @StephenHarris, há um pequeno problema com isso: se houver subdiretórios do seu $PATH , os arquivos nesses subdiretórios poderão ser relatados, mesmo que $PATH não possa alcançá-los. Para contornar isso, você precisaria precisar de find com mais opções do que o POSIX requer. Um GNU-compatível pode contornar isso com:

IFS=':'
find $PATH -maxdepth 1 -type f -executable -exec basename {} \; | sort

O -maxdepth 1 indica find para não entrar em nenhum desses subdiretórios.

    
por 07.04.2017 / 01:58
1

Especificamente para o bash, você pode aproveitar o compgen builtin:

  • compgen -c lista todos os comandos disponíveis, builtins, funções, aliases, etc. (essencialmente tudo o que pode aparecer se você pressionar Tab em um prompt vazio).
  • compgen -b lista todos os internos, similarmente d para diretórios, f para arquivos, a para aliases e assim por diante.

Você pode usar a saída de compgen e abusar de which :

$ compgen -c | xargs which -a
/bin/egrep
/bin/fgrep
/bin/grep
/bin/ls
/bin/ping
/usr/bin/time
/usr/bin/[
/bin/echo
/bin/false
/bin/kill

Os primeiros cinco são na verdade aliases que seguem comandos no meu caso, então temos palavras-chave e builtins, então parece haver alguma ordem para a saída de compgen .

    
por 07.04.2017 / 08:45
0
#!/bin/bash

OLD_IFS=${IFS}
IFS=:

for folder in $PATH
do
        cd ${folder}
        echo "Inside the folder ${folder}"
        for file in *
        do
             if [ -x ${file} ]
             then
                  echo "${file} is executable"
             else
                  echo "${file} is not executable"
             fi
         done
done
IFS=${OLD_IFS}
    
por 07.04.2017 / 01:52
0
IFS=:; set -f;
find -- $PATH -type d -prune -exec sh -c '
cd "$1" && \
find . -type d ! -name . -prune \
           -o \
-type f \( -perm -u+x -o -perm -g+x -o -perm -o+x \) -exec echo Executable File: \{\} \; \
           -o \
-type f  ! -perm -u+x  ! -perm -g+x  ! -perm -o+x    -exec echo Not executable: \{\} \;
' {} {} \;

O IFS é definido como dois-pontos, o separador PATH e a correspondência glob também são inibidos, para impedir qualquer divisão em caracteres glob em nomes encontrados no PATH.

Em seguida, o $ PATH é dividido e apresentado como argumentos principais para find antes de qualquer opção chegar. Nós apenas selecionamos esses argumentos dentre esses que são diretórios. (Se quisermos links para o diretório também, dê a opção -L). E então nós apenas mergulhamos até o primeiro nível nesses diretórios e pegamos os arquivos que são executáveis por alguém (ou seja, usuário / grupo / outro)

    
por 07.04.2017 / 02:58