Por exemplo, verifique se $PWD
é um subdiretório de / home. Em outras palavras, estou procurando por uma operação de seqüência de caracteres bash para verificar se uma sequência começa com outra.
Por exemplo, verifique se $PWD
é um subdiretório de / home. Em outras palavras, estou procurando por uma operação de seqüência de caracteres bash para verificar se uma sequência começa com outra.
Respostas:
Se você deseja testar com segurança se um diretório é um subdiretório de outro, precisará de mais do que apenas uma verificação de prefixo de sequência. A resposta de Gilles descreve em detalhes como fazer esse teste corretamente.
Mas se você deseja uma verificação simples do prefixo de sequência (talvez você já tenha normalizado seus caminhos?), Esta é uma boa:
test "${PWD##/home/}" != "${PWD}"
Se $PWD
começar com "/ home /", ele será retirado do lado esquerdo, o que significa que não corresponderá ao lado direito, então "! =" Retornará verdadeiro.
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
para detectar se o usuário está atualmente em subdir
ou em um subdiretório de subdir
, pois %% captura do final da sequência em vez do início. Isso deve ser útil para qualquer pessoa à procura de mais informações sobre a substituição de parâmetros: tldp.org/LDP/abs/html/parameter-substitution.html
Para testar se uma string é um prefixo de outra, em qualquer shell no estilo Bourne:
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
O mesmo princípio funciona para um teste de sufixo ou substring. Observe que nas case
construções, diferente dos nomes dos arquivos, *
corresponde a qualquer caractere, incluindo um /
ou uma inicial .
.
Nos shells que implementam a [[ … ]]
sintaxe (ou seja, bash, ksh e zsh), ele pode ser usado para combinar uma string com um padrão. (Observe que o [
comando só pode testar cadeias de caracteres para igualdade.)
if [[ $PWD/ = /home/* ]]; then …
Se você estiver testando especificamente se o diretório atual está abaixo /home
, um simples teste de substring não será suficiente, devido a links simbólicos.
Se /home
for um sistema de arquivos próprio, teste se o diretório atual ( .
) está nesse sistema de arquivos.
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
Se você possui o NetBSD, OpenBSD ou GNU (ou seja, Linux) readlink
, pode usar readlink -f
para remover links simbólicos de um caminho.
case $(readlink -f .)/ in $(readlink -f /home)/*) …
Caso contrário, você pode usar pwd
para mostrar o diretório atual. Mas você deve tomar cuidado para não usar um shell interno se o seu shell rastrear cd
comandos e manter o nome que você usou para acessar o diretório em vez de sua localização "real".
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
Versão bruta:
[ ${PWD:0:6} = "/home/" ]
Tem a desvantagem de contar primeiro os caracteres e não se pode substituir /home/
por algo geral $1
.
editar (obrigado @ Michael) pela generalização para comparar com $VAR
um pode usar
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
é o comprimento de $var
, para que você possa generalizá-lo como[ "${PWD:0:${#1}}" = "$1" ]
Eu não entendo a pergunta muito bem, mas para encontrar o pai de $ PWD , faça dirname $PWD
. Para encontrar o pai do pai, execute dirname $(dirname $PWD)
e assim por diante ...
/
. Ok, eu poderia verificar recursivamente, mas não há algo mais fácil?
Usando awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
Hum, é uma pena que [
não tenha uma opção de testar a STRING1 starts with STRING2
condição.
Você pode tentar echo $PWD | grep '^$VAR'
, mas pode falhar de maneiras interessantes quando VAR
contém símbolos especiais.
awk
A index
função de deve poder executar o truque. Mas tudo isso parece pesado demais para uma coisa tão fácil de testar.
Se a parte pesquisada do caminho for encontrada, eu "esvazio" a variável:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
e se essa fosse uma pergunta [code-golf] ( stackoverflow.com/questions/tagged/code-golf)), você teria me vencido em dois caracteres ;-) Também parece mais legível ...