我有一个 shell 脚本问题,我得到了一个充满输入文件的目录(每个文件包含许多输入行),我需要单独处理它们,将它们的每个输出重定向到一个唯一的文件(也就是 file_1.input 需要在 file_1.output 中捕获,依此类推)。
并行前,我只会遍历目录中的每个文件并执行我的命令,同时执行某种计时器/计数技术以免使处理器不堪重负(假设每个进程都有一个恒定的运行时间)。但是,我知道情况并非总是如此,因此使用类似“并行”的解决方案似乎是无需编写自定义代码即可获得 shell 脚本多线程的最佳方法。
虽然我已经想到了一些方法来并行处理这些文件中的每一个(并允许我有效地管理我的内核),但它们似乎都很笨拙。我有一个我认为非常简单的用例,所以我希望尽可能保持干净(并且并行示例中的任何内容似乎都不是我的问题。
任何帮助,将不胜感激!
输入目录示例:
> ls -l input_files/
total 13355
location1.txt
location2.txt
location3.txt
location4.txt
location5.txt
Run Code Online (Sandbox Code Playgroud)
脚本:
> cat proces_script.sh
#!/bin/sh
customScript -c 33 -I -file [inputFile] -a -v 55 > [outputFile]
Run Code Online (Sandbox Code Playgroud)
更新:阅读下面 Ole 的回答后,我能够为我自己的并行实现将缺失的部分放在一起。虽然他的回答很好,但这是我的补充研究和笔记:
我没有运行我的整个过程,而是从概念证明命令开始,以在我的环境中证明他的解决方案。查看我的两个不同的实现(和注释):
find /home/me/input_files -type f -name *.txt | parallel cat /home/me/input_files/{} '>' /home/me/output_files/{.}.out
Run Code Online (Sandbox Code Playgroud)
使用 find(而不是 ls,会导致问题)在我的输入文件目录中查找所有适用的文件,然后将它们的内容重定向到单独的目录和文件。我上面的问题是读取和重定向(实际脚本很简单),所以用 cat 替换脚本是一个很好的概念证明。
parallel cat '>' /home/me/output_files/{.}.out ::: /home/me/input_files/*
Run Code Online (Sandbox Code Playgroud)
第二个解决方案使用并行的输入变量范式来读取文件,但是对于新手来说,这更加令人困惑。对我来说,使用 find a 和 pipe 很好地满足了我的需求。
我编写的大多数代码都是用 PHP 编写的。我最近开始学习 shell 脚本。我遇到的大多数资源和教程都是针对 Bash 的。有些人对 bashisms 提出警告,有些人则没有。我在这里和 Stack Overflow 上读了很多。
每当答案使用bashisms 时,总会有人评论说:
你不应该使用 <insert bashism here>。它不便携。
即使问题被标记为 ,也会发生这种情况bash。对我来说,这就像告诉 PHP 程序员他们不应该使用 PHP 5 中的新代码,因为它不能与 PHP 4 一起使用。或者告诉某人他们不应该为 Mac 编写一些东西,因为它不能使用在 Windows 上。
当我用 PHP 编写时,我会选择一个最低要求并编写向前兼容的代码。我不担心让它向后兼容。
如果我#!/bin/bash用作shebang,为什么不应该使用bashisms?我开始觉得有些人只是为了它而喜欢抨击bashisms(双关语)。
人们经常使用bash和shell互换——可能是因为 bash 是许多系统上的默认 shell。所以我可以理解添加注释来警告代码使用 bashisms,但我不明白使用它们是错误的含义。
显然,如果我编写的脚本严格供个人使用,我可以用我想要的任何语言编写它。但我想我写的一些代码可能对其他人有用。
在发布之前,我尝试搜索我的问题的答案。我找到了很多关于如何测试可移植性的信息,但找不到任何关于何时这样做很重要的信息。
那么,何时编写可移植脚本很重要?
例如,
我在脚本中使用以下命令对 eMMC 进行分区,
parted /dev/mmcblk0 --script mklabel gpt
parted /dev/mmcblk0 --script mkpart primary ext4 32MB 132MB
parted /dev/mmcblk0 --script mkpart primary ext4 233MB 433MB
parted /dev/mmcblk0 --script mkpart primary ext4 433MB 533MB
parted /dev/mmcblk0 --script mkpart primary ext4 533MB 593MB
parted /dev/mmcblk0 --script mkpart primary ext4 593MB 793MB
parted /dev/mmcblk0 --script mkpart primary ext4 793MB 3800MB
parted /dev/mmcblk0 --script align-check min 1
Run Code Online (Sandbox Code Playgroud)
创建第一个分区后,我收到以下警告
警告:生成的分区没有正确对齐以获得最佳性能。
我需要担心吗?我试过了,parted /dev/mmcblk0 --script align-check min 1但不确定那是解决方案。任何指示?
我正在浏览此链接,同时还有其他建议吗?
编辑:只是froschutz回复的快速参考,
MiB = …Run Code Online (Sandbox Code Playgroud) 我正在将 postgresql 安装到第二台服务器上
以前我安装了 postgresql,然后使用了提供的脚本
./contrib/start-scripts/linux
Run Code Online (Sandbox Code Playgroud)
放入正确的目录
# cp ./contrib/start-scripts/linux /etc/rc.d/init.d/postgresql92
# chmod 755 /etc/rc.d/init.d/postgresql92
Run Code Online (Sandbox Code Playgroud)
然后我可以按预期执行
# service postgresql92 start
Run Code Online (Sandbox Code Playgroud)
然而,新机器使用的是 Systemd,看起来有一种完全不同的方法来做到这一点
我不想破解并破坏某些东西,所以我想知道是否有人可以指出我如何实现相同结果的正确方向
测试文件
#!/bin/bash
echo "Hello World"
Run Code Online (Sandbox Code Playgroud)
测试2.sh
#!/bin/bash
while true
do
sh test.sh >> /script_logs/test.log &
done
Run Code Online (Sandbox Code Playgroud)
我想实现logrotate来控制日志文件的大小,那么如何实现logrotate,如果是上面的情况呢?
我想为 Web 应用程序实现 top 功能。是否可以top在非交互式 shell 中获取命令的输出?
如果当前时间在 23:00 和 06:30 之间,我无法掌握如何从 bash 脚本中正确检查。我正在尝试运行一个无限循环来检查现在的时间,并在时间范围在晚上 11 点到早上 6 点 30 之间时做一些事情。这是我到目前为止所写的内容,第二天不起作用:
fireup()
{
local starttime=$(date --date="23:00" +"%s")
local endtime=$(date --date="06:30" +"%s")
while :; do
local currenttime=$(date +%s)
if [ "$currenttime" -ge "$starttime" -a "$currenttime" -ge "$endtime" ]; then
do_something
else
do_something_else
fi
test "$?" -gt 128 && break
local currenttime=$(date +%s)
done &
}
Run Code Online (Sandbox Code Playgroud)
我做错了什么?
我编程的Linux shell脚本,将只有在合适的工具,比如它的执行过程中打印状态横幅figlet,被安装(是这样的:到达系统的路径)。
例子:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Run Code Online (Sandbox Code Playgroud)
我想为我的脚本工作无差错,即使figlet在没有安装。
什么是实用的方法?
我有兴趣完全学习shell脚本。谁能推荐一些好的在线资源?
scripting ×10
shell ×4
bash ×3
linux ×3
date ×1
executable ×1
gnu-parallel ×1
logrotate ×1
parallelism ×1
parted ×1
partition ×1
portability ×1
postgresql ×1
shell-script ×1
systemd ×1
top ×1