Como obteria apenas o nome do diretório de trabalho atual em um script bash ou, melhor ainda, apenas um comando de terminal.
pwd
fornece o caminho completo do diretório de trabalho atual, por exemplo, /opt/local/bin
mas eu só querobin
Como obteria apenas o nome do diretório de trabalho atual em um script bash ou, melhor ainda, apenas um comando de terminal.
pwd
fornece o caminho completo do diretório de trabalho atual, por exemplo, /opt/local/bin
mas eu só querobin
Respostas:
Não há necessidade de nome de base e, especialmente, não é necessário um subshell executando o pwd (que adiciona uma operação de garfo extra e cara ); o shell pode fazer isso internamente usando a expansão de parâmetros :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
Observe que, se você estiver aplicando essa técnica em outras circunstâncias (não PWD
, mas em alguma outra variável com um nome de diretório), poderá ser necessário aparar as barras finais. A seguir, use o suporte extglob do bash para funcionar mesmo com várias barras finais:
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
Como alternativa, sem extglob
:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWD
é o nome de uma variável bash interna ; todos os nomes de variáveis integrados estão em maiúsculas (para diferenciá-los das variáveis locais, que sempre devem ter pelo menos um caractere minúsculo). result=${PWD#*/}
faz não avaliar a /full/path/to/directory
; em vez disso, retira apenas o primeiro elemento, tornando-o path/to/directory
; o uso de dois #
caracteres faz com que o padrão seja ganancioso, correspondendo ao máximo de caracteres possível. Leia a página de expansão de parâmetros, vinculada na resposta, para mais informações.
pwd
nem sempre é igual ao valor de $PWD
, devido a complicações decorrentes de cd
links simbólicos, se o bash tem a -o physical
opção definida e assim por diante. Isso costumava ficar especialmente desagradável ao lidar com diretórios montados automaticamente, onde a gravação do caminho físico em vez do lógico produziria um caminho que, se usado, permitiria ao montador desmontar espontaneamente o diretório que estava usando.
sh
e csh
e se você queria a tecla de retrocesso para o trabalho que você tinha que ler toda stty
página do homem, e nós gostamos!"
Use o basename
programa. Para o seu caso:
% basename "$PWD"
bin
basename
programa? O que há de errado com essa resposta, além de perder as aspas?
basename
é de fato um programa externo que faz a coisa certa, mas a execução de qualquer programa externo para uma festança coisa pode fazer out-of-the-box usando apenas funcionalidade interna é bobagem, incorrendo impacto no desempenho ( fork()
, execve()
, wait()
, etc) para sem motivo.
basename
aqui não se aplicam dirname
, porque dirname
tem uma funcionalidade que ${PWD##*/}
não - transformar uma string sem barras para .
, por exemplo. Portanto, embora o uso dirname
como ferramenta externa tenha sobrecarga de desempenho, também possui funcionalidade que ajuda a compensar a mesma.
function
palavra-chave é incompatível com POSIX sem adicionar nenhum valor à sintaxe padronizada, e a falta de aspas criaria erros nos nomes de diretórios com espaços. wdexec() { "./$(basename "$PWD")"; }
pode ser uma alternativa preferível.
basename
é menos "eficiente". Mas é provavelmente mais eficiente em termos de produtividade do desenvolvedor, porque é fácil de lembrar em comparação com a feia sintaxe do bash. Então, se você se lembra, vá em frente. Caso contrário, basename
funciona tão bem. Alguém já teve que melhorar o "desempenho" de um script bash e torná-lo mais eficiente?
$ echo "${PWD##*/}"
O que outras pessoas estão dizendo
echo "${PWD##*/}"
.
name=${PWD##*/}
estaria certo e name=$(echo "${PWD##*/}")
errado (no sentido de ineficiência desnecessária).
Você pode usar uma combinação de pwd e basename. Por exemplo
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
Gosto da resposta selecionada (Charles Duffy), mas tenha cuidado se você estiver em um diretório com link simbólico e quiser o nome do diretório de destino. Infelizmente, não acho que isso possa ser feito em uma expressão de expansão de parâmetro único, talvez eu esteja enganado. Isso deve funcionar:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
Para ver isso, um experimento:
cd foo
ln -s . bar
echo ${PWD##*/}
relatórios "barra"
Para mostrar os principais diretórios de um caminho (sem incorrer em um fork-exec de / usr / bin / dirname):
echo ${target_PWD%/*}
Isto irá, por exemplo, transformar foo / bar / baz -> foo / bar
readlink -f
é uma extensão GNU e, portanto, não está disponível nos BSDs (incluindo o OS X).
echo "$PWD" | sed 's!.*/!!'
Se você estiver usando o Bourne shell ou ${PWD##*/}
não estiver disponível.
${PWD##*/}
é o POSIX sh - todo moderno / bin / sh (incluindo dash, ash, etc) suporta; para atingir o Bourne real em uma caixa recente, você precisa estar em um sistema Solaris levemente antigo. Além disso - echo "$PWD"
; deixar de fora as aspas leva a erros (se o nome do diretório tiver espaços, caracteres curinga, etc.).
Surpreendentemente, ninguém mencionou essa alternativa que usa apenas comandos bash internos:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
Como um bônus adicional, você pode facilmente obter o nome do diretório pai com:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
Eles funcionarão no Bash 4.3-alpha ou mais recente.
Usar:
basename "$PWD"
OU
IFS=/
var=($PWD)
echo ${var[-1]}
Volte o IFS (Internal Filename Separator) de volta ao espaço.
IFS=
Há um espaço após o IFS.
basename $(pwd)
ou
echo "$(basename $(pwd))"
pwd
é dividida em cadeia e expandida antes de ser passada para basename
.
basename "$(pwd)"
- apesar de que é muito ineficiente em comparação com apenas basename "$PWD"
, que é em si ineficiente em comparação ao uso de uma expansão de parâmetros em vez de chamar basename
a todos.
Para os jóqueis por aí como eu:
find $PWD -maxdepth 0 -printf "%f\n"
$PWD
para "$PWD"
para manipular corretamente nomes de diretório incomuns.
Eu costumo usar isso em scripts sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
você pode usar isso para automatizar as coisas ...
Abaixo grep com regex também está funcionando,
>pwd | grep -o "\w*-*$"
Apenas use:
pwd | xargs basename
ou
basename "`pwd`"
xargs
formulação é ineficiente e com erros quando os nomes de diretório contêm linhas de nova linha literais ou caracteres de aspas, e a segunda formulação chama o pwd
comando em uma subshell, em vez de recuperar o mesmo resultado por meio de uma expansão variável interna.
Se você quiser ver apenas o diretório atual na região do prompt do bash, poderá editar o .bashrc
arquivo ~
. Mude \w
para \W
na linha:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
Execute source ~/.bashrc
e ele exibirá apenas o nome do diretório na região do prompt.
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
Eu prefiro usar gbasename
, que faz parte do GNU coreutils.
basename
lá. Normalmente, ele é chamado apenas gbasename
no MacOS e em outras plataformas que são fornecidas com um nome de base não-GNU.
Os comandos a seguir resultarão na impressão do diretório de trabalho atual em um script bash.
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1
contenha o diretório de trabalho atual. (2) O pushd
e popd
não serve para nada aqui, porque qualquer coisa dentro dos backticks é feita em um subshell - portanto, não pode afetar o diretório do shell pai para começar. (3) O uso "$(cd "$1"; pwd)"
seria mais legível e flexível em relação aos nomes de diretório com espaço em branco.