首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并行运行if条件

并行运行if条件
EN

Unix & Linux用户
提问于 2023-05-28 13:11:37
回答 2查看 54关注 0票数 0

我的剧本是这样的:

代码语言:javascript
复制
#!/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

在这里,如果这两个if代码块并行运行会更好。但是,if代码块中的stdout & stderr应该是分组的(我的意思是它们的输出不应该重叠)。我的意思是:

以下三行的stdout和stderr应该在我们到达第一个if-fi代码块结束后显示。

代码语言:javascript
复制
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"

以下三行的stdout和stderr应该在我们到达第二个if代码块结束后显示。

代码语言:javascript
复制
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"

我怎样才能做到这一点?

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2023-05-28 13:41:06

要序列化这些输出(和错误),您必须临时保存其中的至少一个:

代码语言:javascript
复制
#! /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

这里使用zsh的S =(...)进程替换形式创建临时文件。使用sh或bash,您可以使用系统上可用的mktemp或其他命令安全地创建临时文件。

严格地说,当zsh在展开的命令完成后立即删除临时文件时,=(cmd)并不意味着要这样使用。在这里,我们稍后使用相同的路径重新创建它,因此它并不是严格安全的,因为有一个小窗口,在这个窗口中,恶意参与者可以将文件重新创建为符号链接。

对于任何数量的并行卸载,我们可以分解一些东西。我们还可以向那些将要删除的诱惑文件打开fds,以便从一开始就删除它们,解决上面的问题并整理清理:

代码语言:javascript
复制
#! /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

(未经测试)

票数 2
EN

Unix & Linux用户

发布于 2023-05-30 00:05:22

这是否有效:

代码语言:javascript
复制
#!/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

或者:

代码语言:javascript
复制
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
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/747373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档