ars*_*nal 5 linux shell bash scp multithreading
我试图从复制文件machineB和machineC成machineA,因为我上运行我下面的shell脚本machineA。
如果文件不在那里,machineB那么它machineC肯定应该在那里,所以我会先尝试复制文件machineB,如果它不在那里,machineB那么我会尝试从machineC.
我正在使用 GNU Parallel 库并行复制文件,并且工作正常。目前我正在并行复制两个文件。
目前,我正在使用 GNU 并行复制PRIMARY_PARTITION文件PRIMARY夹中的文件,一旦完成,然后我使用相同的 GNU 并行复制SECONDARY_PARTITION文件SECONDARY夹中的文件,因此它现在是顺序的 wrtPRIMARY和SECONDARY文件夹
下面是我的 shell 脚本,一切正常 -
#!/bin/bash
export PRIMARY=/test01/primary
export SECONDARY=/test02/secondary
readonly FILERS_LOCATION=(machineB machineC)
export FILERS_LOCATION_1=${FILERS_LOCATION[0]}
export FILERS_LOCATION_2=${FILERS_LOCATION[1]}
PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers
export dir3=/testing/snapshot/20140103
# delete primary files first and then copy
find "$PRIMARY" -mindepth 1 -delete
do_CopyInPrimary() {
el=$1
scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/.
}
export -f do_CopyInPrimary
parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}"
# delete secondary files first and then copy
find "$SECONDARY" -mindepth 1 -delete
do_CopyInSecondary() {
el=$1
scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/.
}
export -f do_CopyInSecondary
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}"
Run Code Online (Sandbox Code Playgroud)
问题陈述:-
有什么办法可以启动两个线程,一个是PRIMARY使用与上面相同的设置复制文件夹中的文件,这意味着它将并行复制两个文件。第二个线程SECONDARY使用与我上面相同的设置复制文件夹中的文件,它还应该同时并行复制两个文件吗?
这意味着他们应该同时在文件夹PRIMARY和SECONDARY文件夹中并行复制文件,而不是在PRIMARY文件夹完成后,然后复制文件SECONDARY夹中的文件。
目前,一旦PRIMARY文件夹文件完成,那么只有我尝试复制文件SECONDARY夹中的文件。
简而言之,我只需要启动两个线程,一个线程就会运行这个 -
# delete primary files first and then copy
find "$PRIMARY" -mindepth 1 -delete
do_CopyInPrimary() {
el=$1
scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $PRIMARY/.
}
export -f do_CopyInPrimary
parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}"
Run Code Online (Sandbox Code Playgroud)
第二个线程将运行这个 -
# delete secondary files first and then copy
find "$SECONDARY" -mindepth 1 -delete
do_CopyInSecondary() {
el=$1
scp david@$FILERS_LOCATION_1:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/. || scp david@$FILERS_LOCATION_2:$dir3/new_weekly_2014_"$el"_200003_5.data $SECONDARY/.
}
export -f do_CopyInSecondary
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}"
Run Code Online (Sandbox Code Playgroud)
一旦所有文件复制成功,它应该回显消息,所有文件都被复制。在 java 中,我知道如何启动两个线程,每个线程都在执行某些任务,但不确定在 bash shell 脚本中这将如何工作?
我的主要任务是同时在PRIMARY文件夹和SECONDARY文件夹中使用 GNU 并行复制两个文件?
这可以在 bash shell 脚本中完成吗?
Bash 不支持线程,但它支持后台多处理。也就是说,进程被克隆到一个新的进程空间,有自己的环境、工作目录等,所有的通信都必须通过正常的 IPC 通道发生。但除此之外,它看起来很像线程。
您可以通过“背景化”一个代码块来做到这一点。像这样:
#!/bin/bash
{
echo "Foo"
sleep 1
echo "Foo: done"
}&
echo "Bar"
sleep 1
echo "Bar: done"
Run Code Online (Sandbox Code Playgroud)
输出
Bar
Foo
**[1 second delay]**
Bar: done
Foo: done
Run Code Online (Sandbox Code Playgroud)
您可以通过将代码块包装在函数中并将该函数作为后台作业运行来获得相同的效果。
或者,您可以将代码块包装在括号中而不是大括号中。括号中的语句显式(并且始终)在单独的进程中运行;通常大括号中的语句被分组但不分叉地运行。通过使用&后缀在后台运行代码会强制该代码在单独的进程中运行。
显而易见的是:
parallel -j 2 do_CopyInPrimary ::: "${PRIMARY_PARTITION[@]}" &
parallel -j 2 do_CopyInSecondary ::: "${SECONDARY_PARTITION[@]}" &
wait
Run Code Online (Sandbox Code Playgroud)
但这样,辅助服务器不会等待主服务器完成,也不会检查主服务器是否成功。让我们假设 $PRIMARY_PARTITION[1] 对应于 $SECONDARY_PARTITION[1] (因此,如果您无法从 $PRIMARY_PARTITION[1] 读取文件,您将从 $SECONDARY_PARTITION[1] 读取它 - 这也意味着 $PRIMARY_PARTITION 和 $SECONDARY_PARTITION具有相同数量的元素)。然后您可以在 $PRIMARY_PARTITION[1] 上调节 $SECONDARY_PARTITION[1] 的运行。
do_Copy() {
PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers
pel=${PRIMARY_PARTITION[$1]}
sel=${SECONDARY_PARTITION[$1]}
do_CopyInPrimary $pel ||
do_CopyInSecondary $sel ||
echo Could not copy neither $pel nor $sel
}
export -f do_Copy
# Number of elements in PRIMARY_PARTITION == SECONDARY_PARTITION
seq ${#PRIMARY_PARTITION[@]} | parallel -j 2 do_Copy
Run Code Online (Sandbox Code Playgroud)
这将使依赖关系正确,但一次总共只能复制 2 个。由于-j4您面临同时进行 4 项初选的风险,因此我们也需要防范这种情况:
do_Copy() {
PRIMARY_PARTITION=(550 274 2 546 278) # this will have more file numbers
SECONDARY_PARTITION=(1643 1103 1372 1096 1369) # this will have more file numbers
pel=${PRIMARY_PARTITION[$1]}
sel=${SECONDARY_PARTITION[$1]}
sem -j2 --fg --id primary do_CopyInPrimary $pel ||
sem -j2 --fg --id secondary do_CopyInSecondary $sel ||
echo Could not copy neither $pel nor $sel
}
export -f do_Copy
# Number of elements in PRIMARY_PARTITION == SECONDARY_PARTITION
seq ${#PRIMARY_PARTITION[@]} | parallel -j 4 do_Copy
Run Code Online (Sandbox Code Playgroud)
sem将主要数量限制为 2 个,次要数量限制为 2 个。