Bash: “intérprete incorreto: muitos níveis de links simbólicos” Erro

1

Recentemente eu fiz um arquivo executável bash com permissões 722 como eu sou quase perpetuamente root. O conteúdo do arquivo é o seguinte:

#!/home/nolan/Documents/test/listFiles

[ $# -lt 1 ] && dirFocus = "" || dirFocus = $1
dirSize=$(ls -a $dirFocus | wc -w)

for ((a = 1; a <= $dirSize; a++)) ; do
    i = 1
    for ITEM in $(ls -a $dirFocus); do
        declare -i i
        declare -i a
        if [ $a -eq $i ]; then
            echo "$a : $ITEM"
        fi
        i = $[ $i + 1 ]
    done
done

Quando executado no terminal usando:

root @ /home/nolan/Documents/test: bash listFiles
1 : .
2 : ..
3 : apple
4 : dirCheck
5 : ifTest
6 : ifTest.txt
7 : listFiles
8 : myscript
9 : nolan.txt
10 : pointer_to_apple
11 : scriptx.sh
12 : Stuff
13 : weekend
14 : weekend2
15 : weekend3

Eu recebo este resultado como esperado. No entanto o segundo que eu faço:

root @ /home/nolan/Documents/test: ./listFiles
bash: ./listFiles: /home/nolan/Documents/test/listFiles: bad interpreter: Too
many levels of symbolic links

É o erro que recebo. O que exatamente está errado? Eu verifiquei outros fóruns, mas eles não parecem pertencer à minha situação.

    
por NolanRudolph 10.08.2018 / 18:45

2 respostas

9

A primeira linha de um script é a linha "shebang". Diz ao kernel (carregador de programas) qual programa executar para interpretar o script. Seu script tenta executar a si mesmo para interpretar o script, que por sua vez se chama para interpretar o interpretador, e assim por diante no infinito do anúncio.

Quando você executa o script com bash filename , o kernel não é invocado e o bash é usado para executar o script que funciona.

Coloque

#! /bin/bash

para a primeira linha e tudo ficará bem.

BTW, crie um usuário com privilégios limitados para experimentar o sistema. Como root , você pode facilmente destruir tudo além do reparo.

    
por 10.08.2018 / 18:50
4

choroba explicou muito bem que seu problema é com o script de shell usando-se como intérprete em vez de bash .

Aqui está uma sugestão para a reimplementação do seu script que

  1. Não contém erros de sintaxe ( dirFocus = "" é, por exemplo, um erro de sintaxe em que = não deve ter espaços ao redor em uma atribuição).

  2. Lida com nomes de arquivos que possuem espaços e novas linhas (o loop na saída de ls desqualifica qualquer nome de arquivo, da mesma forma wc -w teria a contagem errada se algum nome de arquivo contivesse espaços).

  3. Usa sintaxe moderna de shell ( $[ $i + 1 ] é obsoleta bash sintaxe).

  4. Apresenta melhorias minúsculas na saída (adiciona (dir) aos nomes dos diretórios).

#!/bin/bash

shopt -s dotglob    # make wildcards match hidden names by default
shopt -s nullglob   # make wildcards expand to nothing if no match

count=0
for name in "${1:-.}"/*; do
    count=$(( count + 1 ))
    if [ -d "$name" ]; then
        printf '%d : %s (dir)\n' "$count" "${name##*/}"
    else
        printf '%d : %s\n' "$count" "${name##*/}"
    fi
done

Isso também não expande a lista de arquivos mais de uma vez, enquanto seu código faz um ls em todo o diretório para cada nome no diretório.

${1:-.} significa "use o que está em $1 , a menos que esteja vazio ou não definido, caso contrário use . ".

${name##*/} significa "a string em $name , mas sem o bit até o último / ".

    
por 10.08.2018 / 20:05

Tags