Você pode canalizar para uma função .bash_profile?

5

Recebi uma ótima função para realçar arquivos no localizador da Apple usando a linha de comando. É basicamente um wrapper para o osogle.

Eu obtive de Mac OS X: Como alterar o rótulo de cor dos arquivos do Terminal e se parece com isso,

# Set Finder label color
label(){
  if [ $# -lt 2 ]; then
    echo "USAGE: label [0-7] file1 [file2] ..."
    echo "Sets the Finder label (color) for files"
    echo "Default colors:"
    echo " 0  No color"
    echo " 1  Orange"
    echo " 2  Red"
    echo " 3  Yellow"
    echo " 4  Blue"
    echo " 5  Purple"
    echo " 6  Green"
    echo " 7  Gray"
  else
    osascript - "$@" << EOF
    on run argv
        set labelIndex to (item 1 of argv as number)
        repeat with i from 2 to (count of argv)
          tell application "Finder"
              set theFile to POSIX file (item i of argv) as alias
              set label index of theFile to labelIndex
          end tell
        end repeat
    end run
EOF
  fi
}

Eu coloquei via vim .bash_profile , executei source .bash_profile e consegui executar a função com label 2 /Users/brett/Desktop/test.txt . Perfeito.

Mas e se eu estiver atualizando todo o nosso antigo PHP mysql_query (instruções para o PDO e eu quero destacar visualmente os arquivos que eu preciso editar?

Eu normalmente corria,

find /Users/brett/Development/repos/my-repo/ -name "*.php" -print0 | xargs -0 grep -Iil 'mysql_query(' | xargs -I '{}' -n 1 label 2 {}

Mas isso retorna,

xargs: label: No such file or directory

Eu li que deveria tentar executar export -f label , mas isso também não parece ajudar.

Alguém sabe como posso canalizar caminhos / arquivos de grep a xargs para uma função .bash_profile?

    
por bafromca 01.08.2013 / 19:25

3 respostas

4

Para chamar label com xargs , você pode tentar algo assim:

export -f label
find /Users/brett/Development/repos/my-repo/ -name "*.php" -print0 |
  xargs -0 grep -Iil 'mysql_query(' |
  xargs -I {} -n 1 bash -c 'label 2 {}'

Observe como label 2 {} na última chamada xargs foi alterada para bash -c 'label 2 {}' . Como xargs não pode chamar a função diretamente, nós exportamos a função label para child bash processes do shell pai, então bifurcamos um shell filho e processamos a função lá.

Notas:

  • ~/.bash_profile normalmente não é originado por shells que não são de login, portanto export -f label é necessário para exportar a função label para o shell chamado por xargs .

  • A opção -c informa bash para ler os comandos a serem executados a partir da sequência de argumentos da opção.

por 01.08.2013 / 21:39
3

Por que você não faz o contrário? Encontre os arquivos em questão e processe-os em um loop em vez de usar xargs . Tantas respostas neste e em outros sites recomendam xargs que as pessoas parecem achar que é sempre a melhor ferramenta para o trabalho.

find /Users/brett/Development/repos/my-repo/ -name "*.php" |
  while IFS= read -r file; do grep -Iil 'mysql_query(' "$file" && label 2 "$file"

Este comando encontrará os arquivos .php , salvará cada um deles como $file , executará grep neles e, se o grep corresponder, passará para a sua função. Não posso testar isso, pois não tenho um Mac, mas ele deve funcionar perfeitamente bem.

    
por 01.08.2013 / 20:22
1

Você não pode usar uma função fora da (s) instância (s) da shell onde ela está definida. Como essa função está em .bash_profile , ela está disponível apenas em shells de login, não em shells iniciados em um terminal X (exceto no OSX que inicia shells de login no Terminal) nem em shells executando scripts de arquivos ou de sua linha de comando. As funções não podem ser chamadas por outros programas, como xargs .

Embora existam soluções alternativas baseadas em invocar o shell para iniciar a função, a solução mais simples é colocar o código da sua função em um script. Dessa forma, ele pode ser invocado em qualquer lugar.

Nem todas as funções podem ser scripts independentes, porque os scripts independentes não podem afetar seu shell pai (eles não podem ver variáveis não exportadas, eles não podem definir qualquer variável no pai, etc.). Aqui, sua função não faz nada que exija a execução dentro do shell pai, então você pode também torná-lo um script.

    
por 02.08.2013 / 02:39