entendendo meu script de shell [closed]

3

Eu escrevi uma função para usar no bash para montar automaticamente um diretório em ~/tmp e criar um, se não estiver lá:

# mkdir & mount auto
mnt() {
    dir="$1";
    mkdir ~/tmp/$dir;
    /usr/bin/sudo mount /dev/$dir ~/tmp/$dir;
    cd ~/tmp/$dir;
}

Algumas perguntas ...

dir="$1";

define variável dir para qualquer que seja a entrada após mnt
- o $1 precisa ser encapsulado em "" e é necessário haver um ; após cada linha? funcionaria sem o ; ?

/usr/bin/sudo mount /dev/$dir ~/tmp/$dir;

Eu assisti a um vídeo no youtube Tudo o que você precisa saber sobre o $ PATH no Bash

que em scripts eu deveria escrever caminhos completos ...

/usr/bin/sudo 

em vez de ...

sudo

qual é o raciocínio por trás disso?

    
por m147 30.12.2017 / 20:03

2 respostas

7

Uma versão melhor desta função:

mnt() {
  typeset dir # for local scope for the variable.
              # assumes ksh88/pdksh/bash/zsh/yash. Replace typeset with
              # local for ash-based shells (or pdksh/bash/zsh)

  dir=$1 # here it's the only place where you don't need the quotes
         # though they wouldn't harm

  mkdir -p -- ~/tmp/"$dir" || return
     # quotes needed. mkdir -p creates intermediary directories as required
     # and more importantly here, doesn't fail if the directory already
     # existed.
     # We return from the function if mkdir failed (with the exit status
     # of mkdir). The -- is for the very unlikely even that your $HOME starts
     # with "-". So you may say it's a pedantic usage here. But it's good
     # habit to use it when passing an arbitrary (not known in advance)
     # argument to a command.

  sudo mount "/dev/$dir" ~/tmp/"$dir" || return
     # Or use /usr/bin/sudo if there are more than one sudo commands in $PATH
     # and you want to use the one in /usr/bin over other ones.
     # If you wanted to avoid calling an eventual "sudo" function  or alias 
     # defined earlier in the script or in a shell customisation file, 
     # you'd use "command sudo" instead.

  cd -P -- ~/tmp/"$dir" # another pedantic use of -P for the case where
                        # your $HOME contains symlinks and ".." components
}

Ponto-e-vírgula não é necessário. Enquanto no prompt do seu shell, você escreve:

cd /some/where
ls

Não

cd /some/where;
ls;

Não é diferente em scripts. Você usa ; para separar comandos em uma linha como em:

cd /some/where; ls

No entanto, você prefere escrever:

cd /some/where && ls

Isso não é executado ls incondicionalmente, mas somente se cd for bem-sucedido.

    
por 30.12.2017 / 23:58
5

Perguntas:

  • os $ 1 precisam ser encapsulados em ""

    Short answer is yes

Mais leitura

  • precisa haver um; depois de cada linha? funcionaria sem o?

    The ; is a command separator and is only necessary if multiple commands are on the same line like: echo "Hello, World"; echo. When the commands are on separate lines like in your script it is unecessary but wont break anything.

  • Por que devo especificar um caminho completo em vez de apenas o nome do comando?

    When you simply type a command name your path is parsed for the first occurrence of that command. It is not uncommon to have multiple commands in different locations, especially with the existence of GNU tools and other variations of the same commands. If you don't specify the full path of the command you are using, your shell will decide which to use, and it may not be the one you really want.

Eu meio que discordo de sempre especificando o caminho completo porque na minha experiência isso geralmente não é necessário e eu apenas ligo para que ele encontre alguma versão da ferramenta. Existem exceções, mas acho que você deve entendê-las melhor antes de considerá-las. Por exemplo, em meu ambiente, temos principalmente máquinas unix que não são padrão para ferramentas GNU, entretanto muitas das ferramentas estão instaladas nas máquinas, então se eu precisar usar a versão GNU de uma ferramenta contra uma dessas máquinas eu preciso especificar o caminho completo para essa ferramenta.

mnt() {
    dir="$1";                                   # Sets the value of dir to your first positional parameter
    mkdir ~/tmp/$dir;                           # Creates your a directory named after the value of $dir in $HOME/tmp/
    /usr/bin/sudo mount /dev/$dir ~/tmp/$dir;   # Mounts the device in /dev/$dir to your newly created folder (You better hope you set $1 properly)
    cd ~/tmp/$dir;                              # changes to your newly created/mounted directory.
}
    
por 30.12.2017 / 20:42