Como tornar executável de todos os arquivos, excluindo alguns tipos de arquivo?

4

Eu tenho uma pasta contendo muitos arquivos fonte C e o mesmo número de seus arquivos de saída compilados.

Eu configurei o bit executável para todos esses arquivos, mas por algum motivo ele foi perdido, tornando-os não executáveis. (acho que é porque eu mudei essa pasta para uma partição NTFS por um tempo) .

Eu gostaria de torná-los (mas não os outros arquivos em meu diretório) executáveis novamente. Uma maneira possível é mover todo o arquivo de origem dessa pasta para uma pasta temporária e fazer:

chmod +x *

Em seguida, mova os arquivos de origem de volta para a pasta atual.

É possível fazer o mesmo sem mover arquivos?

Nota:

Os arquivos de saída compilados são sem extensão (em C) .

    
por Santosh Kumar 04.10.2012 / 14:11

4 respostas

12

Isso depende de como você define quais arquivos devem ser configurados como executáveis. Por exemplo, se considerar todos os arquivos que não possuem ponto no nome do arquivo, você pode usar:

find -type f -not -name "*.*" -exec chmod +x \{\} \;

Isto irá encontrar recursivamente todos os arquivos (não diretórios) que não possuem ponto no nome do arquivo e configurá-los como executáveis. Se você quiser limitar isso apenas ao diretório atual, adicione -maxdepth 1 argument, como este:

find -maxdepth 1 -type f -not -name "*.*" -exec chmod +x \{\} \;

Você também pode confiar no comando file , que poderia dizer se um arquivo é um executável ELF. Para fazer isso, você pode executar algo como:

find -type f -exec /bin/sh -c "file {} | grep -q executable && chmod +x {}" \;

Isto irá recursivamente encontrar todos os arquivos regulares e chamar o comando file neles. Então, o grep irá procurar pela string "executável" na saída deste comando (deve ser algo como ELF 32-bit LSB executable ... ) e somente se encontrar, chmod será chamado neste arquivo.

É claro que você também pode adicionar -maxdepth 1 para desativar a pesquisa recursiva.

    
por 04.10.2012 / 17:55
4

Você pode fazer algo como:

find /pathtostuff -type f ! -name "*.c" -exec chmod +x {} +

Isso parece em /pathtostuff para arquivos que não possuem uma extensão .c e adiciona as permissões de execução a eles.

UPDATE

Isso também pode ser expandido para lidar com outras extensões C:

find . -type f ! -name "*.c" ! -name "*.h" ! -name "*.cc" ! -name "*.cpp" -exec chmod +x {} +

ABORDAGEM ALTERNATIVA

Este script é agnóstico à extensão. Ele procura arquivos que são "binários" em oposição a "texto".

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
my @dir = @ARGV ? @ARGV : ('.');
my @files;
find( sub { -f $_ && !-T $_ && push @files, $File::Find::name }, @dir );
for my $file (@files) {
    system("echo  +x $file");
}

Basta passar o caminho do diretório a ser examinado. Execute o script sem nenhum argumento para processar o diretório de trabalho atual.

    
por 04.10.2012 / 14:45
3

No zsh:

setopt extendedglob
chmod +x -- ^*.c

Com ksh, ou bash com opção extglob , ou zsh com kshglob option:

chmod +x -- !(*.c)

Com ksh93 (provavelmente melhor evitar jogar com o FIGNORE):

FIGNORE='@(.*|*.c)'
chmod +x -- *

Para todos, substitua *.c por *.* para excluir qualquer coisa que tenha um ponto.

Com o zsh, você pode fazer coisas legais com qualificadores de globbing, como:

oftype() [[ $(file -b --mime-type -- $REPLY) = $type ]]
type=application/x-executable; chmod +x -- **/*(.+oftype)

Qual seria a correspondência em arquivos regulares "oftype" application/x-executable (descendente recursivamente em subdiretórios).

    
por 04.10.2012 / 15:17
1

Isso também provavelmente funcionaria

chmod +x $(find . -type f -print0 | xargs -0 file | grep "ELF [^,;]* executable" |  cut -d: -f1)

Você ainda terá problemas se os arquivos contiverem espaços, tabulações, novas linhas, asteriscos, pontos de interrogação, colchetes angulares ou caracteres de barra invertida nos nomes ou se houver muitos deles para caber em uma linha de comando.

    
por 04.10.2012 / 15:17

Tags