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 / 747373
Accepted
Ahmad Ismail
Ahmad Ismail
Asked: 2023-05-28 21:11:37 +0800 CST2023-05-28 21:11:37 +0800 CST 2023-05-28 21:11:37 +0800 CST

Executar se as condições em paralelo

  • 772

Eu tenho um script como:

#!/bin/bash

if findmnt --source UUID=309689b5-ea5c-4175-84c7-192631553eab --source PARTLABEL=WDPurple8TB --mountpoint /media/ismail/WDPurple8TB --types ext4 --noheadings; then
    udisksctl unmount -b /dev/disk/by-label/WDPurple8TB
    udisksctl power-off -b /dev/disk/by-label/WDPurple8TB
    echo "Power-Off /dev/disk/by-label/WDPurple8TB"
fi

if findmnt --source UUID=151cf7f0-461a-416f-8e44-63d799418958 --source PARTLABEL=WDPurple6TB --mountpoint /media/ismail/WDPurple6TB --types ext4 --noheadings; then
    udisksctl unmount -b /dev/disk/by-label/WDPurple6TB
    udisksctl power-off -b /dev/disk/by-label/WDPurple6TB
    echo "Power-Off /dev/disk/by-label/WDPurple6TB"
fi

Aqui, seria melhor se ambos os blocos de código if-fi fossem executados em paralelo. No entanto, o stdout & stderr dentro do bloco de código if-fi deve vir em grupo (quero dizer que a saída deles não deve se sobrepor). O que eu quero dizer é:

o stdout & stderr das três linhas seguintes deve aparecer depois de atingirmos o final do primeiro bloco de código if-fi.

udisksctl unmount -b /dev/disk/by-label/WDPurple8TB
udisksctl power-off -b /dev/disk/by-label/WDPurple8TB
echo "Power-Off /dev/disk/by-label/WDPurple8TB"

o stdout & stderr das três linhas a seguir deve aparecer depois de atingirmos o final do segundo bloco de código if-fi.

udisksctl unmount -b /dev/disk/by-label/WDPurple6TB
udisksctl power-off -b /dev/disk/by-label/WDPurple6TB
echo "Power-Off /dev/disk/by-label/WDPurple6TB"

Como posso conseguir isso?

bash
  • 2 2 respostas
  • 54 Views

2 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2023-05-28T21:41:06+08:002023-05-28T21:41:06+08:00

    Para serializar essas saídas (e erros), você teria que salvar pelo menos uma delas temporariamente:

    #! /bin/zsh -
    ret=0
    umask 077 # for temp files that we recreate
    if findmnt --source UUID=309689b5-ea5c-4175-84c7-192631553eab --source PARTLABEL=WDPurple8TB --mountpoint /media/ismail/WDPurple8TB --types ext4 --noheadings; then
        udisksctl unmount -b /dev/disk/by-label/WDPurple8TB &&
          udisksctl power-off -b /dev/disk/by-label/WDPurple8TB &&
          echo "Power-Off /dev/disk/by-label/WDPurple8TB"
    fi & pid=$!
    
    out==() err==()
    if findmnt --source UUID=151cf7f0-461a-416f-8e44-63d799418958 --source PARTLABEL=WDPurple6TB --mountpoint /media/ismail/WDPurple6TB --types ext4 --noheadings; then
        udisksctl unmount -b /dev/disk/by-label/WDPurple6TB &&
          udisksctl power-off -b /dev/disk/by-label/WDPurple6TB &&
          echo "Power-Off /dev/disk/by-label/WDPurple6TB"
    fi > $out 2> $err || ret=$?
    
    wait $pid || ret=$?
    
    # dump the second job's errors on stderr
    cat<$err >&2
    
    # and its output to stdout:
    cat<$out
    
    # clean up the temp files
    rm -f -- $out $err
    
    # report failure if any of any of those two jobs
    exit $ret
    

    Aqui, usando zsha =(...)forma de substituição de processo para criar arquivos temporários. Com sh ou bash, você pode usar mktempou qualquer outro comando disponível em seu sistema para criar arquivos temporários com segurança.

    Estritamente, falar =(cmd)não deve ser usado assim, pois o zsh exclui o arquivo temporário assim que o comando onde ele é expandido termina. Aqui nós o recriamos mais tarde com o mesmo caminho, portanto não é estritamente seguro, pois há uma pequena janela durante a qual o arquivo pode ter sido recriado como link simbólico por um agente mal-intencionado.

    Para qualquer número de desmontagens paralelas, poderíamos fatorizar um pouco as coisas. Também podemos abrir fds para os arquivos temporários a serem excluídos, para que sejam excluídos desde o início, abordando o problema acima e classificando a limpeza:

    #! /bin/zsh -
    zmodload zsh/system || exit
    out=() err_read=() err_write=() out_read=() out_write=() pid=()
    n=1 ret=0
    
    stop_disk() {
      local uuid=$1 label=$2
      if
        findmnt --source UUID=$uuid \
                --source PARTLABEL=$label \
                --mountpoint /media/ismail/$label \
                --types ext4 \
                --noheadings
      then
        udisksctl unmount -b /dev/disk/by-label/$label &&
          udisksctl power-off -b /dev/disk/by-label/$label &&
          print -r "Power-Off /dev/disk/by-label/$label"
      fi
    }
    
    for uuid label (
      309689b5-ea5c-4175-84c7-192631553eab WDPurple8TB
      151cf7f0-461a-416f-8e44-63d799418958 WDPurple6TB
    ) {
      () {
         sysopen -wo cloexec -u out -- $1 &&
           sysopen -ro cloexec -u in -- $1 &&
           err_write[n]=$out err_read[n]=$in &&
           sysopen -wo cloexec -u out -- $2 &&
           sysopen -ro cloexec -u in -- $2 &&
           out_write[n]=$out out_read[n]=$in
      } =() =() || exit
    
      stop_disk $uuid $label >&$out_write[n] 2>&$err_write[n] &
      pid[n++]=$!
    }
    
    for (( i = 1; i <= n; i++ )) {
      wait $pid[i] || ret=$?
      cat <&$err_read[i] >&2
      cat <&$out_read[i]
    }
    
    exit $ret
    

    (não testado)

    • 2
  2. Ole Tange
    2023-05-30T08:05:22+08:002023-05-30T08:05:22+08:00

    Isso funcionaria:

    #!/bin/bash
    
    a() {
        if findmnt --source UUID=309689b5-ea5c-4175-84c7-192631553eab --source PARTLABEL=WDPurple8TB --mountpoint /media/ismail/WDPurple8TB --types ext4 --noheadings; then
            udisksctl unmount -b /dev/disk/by-label/WDPurple8TB
            udisksctl power-off -b /dev/disk/by-label/WDPurple8TB
            echo "Power-Off /dev/disk/by-label/WDPurple8TB"
        fi
    }
    b() {
        if findmnt --source UUID=151cf7f0-461a-416f-8e44-63d799418958 --source PARTLABEL=WDPurple6TB --mountpoint /media/ismail/WDPurple6TB --types ext4 --noheadings; then
            udisksctl unmount -b /dev/disk/by-label/WDPurple6TB
            udisksctl power-off -b /dev/disk/by-label/WDPurple6TB
            echo "Power-Off /dev/disk/by-label/WDPurple6TB"
        fi
    }
    export -f a b
    parallel --lb ::: a b
    

    Ou:

    umnt() {
        uuid="$1"
        label="$2"
        if findmnt --source UUID="$uuid" --source PARTLABEL="$label" --mountpoint /media/ismail/"$label" --types ext4 --noheadings; then
            udisksctl unmount -b /dev/disk/by-label/"$label"
            udisksctl power-off -b /dev/disk/by-label/"$label"
            echo "Power-Off /dev/disk/by-label/$label"
        fi
    }
    export -f umnt
    parallel --lb umnt ::: 309689b5-ea5c-4175-84c7-192631553eab 151cf7f0-461a-416f-8e44-63d799418958 :::+ WDPurple8TB WDPurple6TB
    
    • 1

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

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

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

  • 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