AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 495864
Accepted
L. Levrel
L. Levrel
Asked: 2019-01-22 14:02:37 +0800 CST2019-01-22 14:02:37 +0800 CST 2019-01-22 14:02:37 +0800 CST

Comparando o tempo de um link simbólico

  • 772

Eu quero verificar se o link lnkfileé mais antigo que um arquivo de referência regular reffile.

O bash testbuiltin desreferencia links, portanto, test lnkfile -ot reffilecompara o destino de lnkfile, não o próprio link.

Existe uma maneira de fazer com que o testbuiltin não siga links simbólicos? Caso contrário, como posso comparar o tempo de um link simbólico?

bash shell-script
  • 3 3 respostas
  • 422 Views

3 respostas

  • Voted
  1. Chris Down
    2019-01-22T14:08:58+08:002019-01-22T14:08:58+08:00

    Até onde eu sei, o bash não oferece nenhuma versão -ot(e similares) que evite desreferenciar links simbólicos.

    O que você pode fazer é usar GNU stat (que não desreferencia links simbólicos sem -L) e comparar suas épocas mtime numericamente:

    if (( "$(stat --format=%Z lnkfile)" < "$(stat --format=%Z reffile)" )); then
        # lnkfile is older
    fi
    
    • 3
  2. Best Answer
    Sparhawk
    2019-01-22T14:15:51+08:002019-01-22T14:15:51+08:00

    Eu não acho que haja uma maneira com test, mas você pode usar find.

    test "$(find reffile -prune -newer lnkfile)" && command
    

    Aqui, findretorna a saída se lnkfilefor mais antiga que reffile. testsem uma opção é equivalente a test -n. Isso é verdade se o comprimento da string for diferente de zero. Portanto, se houver saída de find, commandserá executado.


    Nos comentários, me pediram para fazer uma comparação desta solução vs. stat. Em primeiro lugar, acho a statabordagem perfeitamente boa.

    Fiz um benchmark para comparar. Repeti o teste algumas vezes, alternando, e obtive resultados semelhantes.

    $ time (for i in {1..1000}; do test "$(stat --format=%Z a)" -lt "$(stat --format=%Z b)" && echo foo > /dev/null ; done)
    
    ================
    CPU 101%
    CPU 104%
    user    1.264
    system  0.942
    total   2.108
    
    $ time (for i in {1..1000}; do test "$(find b -newer a)" && echo foo > /dev/null ; done)
    
    ================
    CPU 104%
    user    0.693
    system  0.526
    total   1.164
    

    Parece que findé quase duas vezes mais rápido, talvez porque seja um único processo em vez de dois stats? Não tenho certeza de como compará-los; por favor, comente se houver outros aspectos relevantes que você possa pensar.

    Aqui estão algumas outras diferenças, conforme comentários de Stéphane Chazelas abaixo:

    Outras diferenças são: findum é padrão. enquanto o statoutro precisa da implementação GNU do stat. O statúnico não funcionará para arquivos modificados no mesmo segundo (enquanto finddeve funcionar em sistemas em que a granularidade de subsegundo para carimbos de data/hora é suportada). Nem findoferece statsuporte a nomes de arquivos arbitrários.

    Você encontrará outras diferenças se um dos arquivos não puder ser stat()editado.

    • 3
  3. Stéphane Chazelas
    2019-01-23T14:31:43+08:002019-01-23T14:31:43+08:00

    Com zsh5.6 ou superior (para a precisão de nanossegundos), você pode fazer isso com built-ins apenas com:

    zmodload zsh/stat
    if 
      stat -LA lnktime -F '%021s%N' +mtime -- $lnkfile &&
        stat -A reftime -F '%021s%N' +mtime -- $reffile &&
        [[ $lnktime < $reftime ]]
    then
      print -r -- $lnkfile is older than $reffile
    fi
    

    O que funcionaria independentemente de quais caracteres ou não caracteres os nomes dos arquivos contêm e compara os carimbos de data/hora até o nanossegundo.

    Estamos comparando os carimbos de data e hora como strings (número de nanossegundos como uma representação decimal de string com zero de 30 dígitos) em vez de pontos flutuantes porque os pontos flutuantes de precisão dupla típicos de um PC x86_64 executando GNU/Linux pelo menos não têm o suficiente precisão para armazenar números 1548195897.775033155assim, você não seria capaz de distinguir dois arquivos modificados hoje nos mesmos 100 nanossegundos.

    $ ((1548195897.775033155 < 1548195897.775033255)) && echo yes
    $ [[ 1548195897775033155 < 1548195897775033255 ]] && echo yes
    yes
    
    • 1

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • MySQL Select com função IN () com array bash

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve