listar arquivos e armazená-los em variáveis

4

Eu sou novo com a programação shell. Meu objetivo é dar ao usuário uma seleção de qual arquivo deve ser executado. Eu pego todos os scripts disponíveis em um var com:

var=$(find script*)

até aí tudo bem, esta é a saída:

    echo $var
    script1 script2 script3 scr...

agora quero armazenar cada arquivo em uma variável singel para executá-lo na seleção posterior

select SEL in script1 script2 script3 ..........
case $SEL in
        $Script1) echo ($Script1 will start) && ./$script1 ;;
        $Script2) echo ($Script2 will start) && ./$script2 ;;
        $Script3) echo ($Script3 will start) && ./$script3 ;;
        $Sc..) echo ($Scr.... will start) && ./$scrip.... ;;
        $Sc...) echo ($Sc...... will start) && ./$scrip..... ;;
        *) echo "choose on of the availabel files";;
    esac
done

Eu não tenho ideia de como devo separar todos os arquivos se não souber quantos e exatamente o tamanho de cada arquivo.

Eu tentei dividir com echo $ {var [1]} e echo $ var [1], mas isso não deu certo. Eu recebo uma saída vazia ou a string inteira.

    
por Dario 25.06.2014 / 10:50

2 respostas

3

Sua primeira linha:

var=$(find script*)

está apenas transformando var em uma única variável de string com todo script* nela. Não é não um array, então não podemos indexar nele com [] como você deseja.

O script* é realmente expandido pelo shell, então find não está fazendo nada lá (a menos que sejam diretórios, o que não parece que sejam) - ele apenas recebe todos os nomes de arquivos como argumentos , verifica se eles existem e os imprime de volta. A casca realmente faz todo o trabalho ..

Em vez disso, podemos criar um array e podemos usar o href="https://www.gnu.org/software/bash/manual/bashref.html#Filename-Expansion"> expansão glob diretamente para preenchê-lo:

files=(script*)

Quando colocamos o inicializador (o lado direito do = ) entre parênteses, criamos um array, que contém vários valores separadamente. script* expandirá para cada nome de arquivo, começando com script no diretório atual. Se houver espaços nos nomes de arquivos, eles não farão com que as palavras sejam divididas do jeito que seriam com os comandos (backticks ou $() ) dentro do inicializador da matriz.

Neste ponto, podemos ler alguma entrada do usuário:

select SEL in "${files[@]}"
do
    if ! [ "$SEL" ]
    then
        echo "Choose one of the available files."
        continue
    fi
    echo "$SEL will start"
    "./$SEL"
    break
done

Escrevemos "${files[@]}" para expandir toda a nossa matriz de nomes de arquivos para dar a select . Serão oferecidos ao usuário uma opção de arquivos e, em seguida, inseriremos o bloco do...done .

Se $SEL estiver vazio, o usuário escolheu uma entrada inexistente, por isso, imprimimos o prompt e continue , para que eles peçam para escolher novamente.

Caso contrário, echo a notificação de que o script será iniciado e executará o script. Citaremos o nome "./$SEL" caso o nome do script tenha espaços, o que faria com que o nome do comando fosse tratado como ./firstword , com as palavras restantes como argumentos. break nos impede de voltar e perguntar ao usuário novamente; se você quiser fazer isso, retire-o.

O case...of que você estava usando não parece ter muito efeito no exemplo que você dá, mas se você tiver algum comportamento separado, dependendo do script escolhido (e tem que estar em isso script), você pode colocar isso dentro do bloco do...done .

    
por 25.06.2014 / 11:23
1

Não tenho 100% de certeza de que entendi completamente o que você quer fazer, mas isso pode funcionar melhor para você: Em vez de var = $ (find script *) e um caso que você poderia usar melhor

for i in 'find script*'
do
        echo ($i will start) 
        ./$i
done
    
por 25.06.2014 / 11:05