1

我正在尝试.sh从 .Net Core 服务守护进程中执行脚本并获得奇怪的行为。该脚本的目的是创建一个加密容器,对其进行格式化,设置一些设置,然后挂载它。

我在 Raspberry Pi 4 上的 Raspbian 上使用 .Net Core 版本 3.1.4。

问题:我有下面的脚本创建容器,格式化它,设置设置,然后尝试安装它。一切似乎都很好,但最后一个命令 mount call 从来没有真正起作用。挂载点无效。

踢球者:通过服务运行脚本后,如果我打开终端并在那里手动发出安装命令,它会正确安装。然后我可以转到那个挂载点,它显示大约 10GB 的可用空间,这意味着它正在使用容器。

注意:确保脚本chmod +x在测试时。此外,您还需要安装 cryptsetup 才能工作。

想法:

我不确定是否缺少某些环境或 PATH 变量以使 shell 脚本正常运行。Unit由于这是一项服务,如果我知道它是什么,我可以编辑它以包含此信息。

在以前发出 bash 命令的尝试中,我必须DISPLAY像下面这样设置变量才能正常工作(因为需要使用桌面)。对于这个似乎无关紧要的问题,但如果我需要将脚本设置为可执行文件,则使用此命令作为示例

string chmodArgs = string.Format("DISPLAY=:0.0; export DISPLAY && chmod +x {0}", scriptPath);
chmodArgs = string.Format("-c \"{0}\"", chmodArgs);

我想看看是否有人可以采取以下措施并对其进行测试以确认并可能帮助提出解决方案。谢谢!

#!/bin/bash

#       variables
#       s0f4e7n4r4h8x4j4
#       /usr/sbin/content1
#       content1
#       /mnt/content1
#       10240

#       change the size of M to what the size of container should be
echo "Allocating 10240MB..."
fallocate -l 10240M /usr/sbin/content1
sleep 1

#       using echo with -n passes in the password required for cryptsetup command.  The dash at the end tells cryptsetup to read in from console
echo "Formatting..."
echo -n s0f4e7n4r4h8x4j4 | cryptsetup luksFormat /usr/sbin/content1 - 
sleep 1

echo "Opening..."
echo -n s0f4e7n4r4h8x4j4 | cryptsetup luksOpen /usr/sbin/content1 content1 - 
sleep 1

#       create without journaling
echo "Creating filesystem..."
mkfs.ext4 -O ^has_journal /dev/mapper/content1
sleep 1

#       enable writeback mode
echo "Tuning..."
tune2fs -o journal_data_writeback /dev/mapper/content1
sleep 1

if [ ! -d "/mnt/content1" ]; then
  echo "Creating directory..."
  mkdir -p /mnt/content1
  sleep 1
fi

#       mount with no access time to stop unnecessary writes to disk for just access
echo "Mounting..."
mount /dev/mapper/content1 /mnt/content1 -o noatime
sleep 1

这就是我在 .Net 中执行脚本的方式

var proc = new System.Diagnostics.Process {
    StartInfo =
        {
            FileName = pathToScript,
            WorkingDirectory = workingDir,
            Arguments = args,
            UseShellExecute = false
        }
};

if (proc.Start())
{
    while (!proc.HasExited)
    {
        System.Threading.Thread.Sleep(33);
    }
}

Unit用于服务守护程序的文件

[Unit]
Description=Service name

[Service]
ExecStart=/bin/bash -c 'PATH=/sbin/dotnet:$PATH exec dotnet myservice.dll'
WorkingDirectory=/sbin/myservice/
User=root
Group=root
Restart=on-failure
SyslogIdentifier=my-service
PrivateTmp=true

[Install]
WantedBy=multi-user.target
4

1 回答 1

0

问题是无法mount直接从服务中运行命令。从广泛的试验和错误中,即使打印mount命令的详细信息也会表明没有错误并且不会被安装。不为用户提供一些失败消息非常具有误导性。

解决方案是创建一个Unit文件“服务”来处理挂载/卸载。下面解释了一个链接,该链接指向将我带到这里的鼓舞人心的文章。

第 1 步:创建单元文件

关键是.mount文件需要以与Where=单元文件中的匹配的模式命名。因此,如果您正在安装/mnt/content1,您的文件将是:

sudo nano /etc/systemd/system/mnt-content1.mount

这是我使用的单元文件详细信息。

[Unit]
Description=Mount Content (/mnt/content1)
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target
After=swap.target

[Mount]
What=/dev/mapper/content1
Where=/mnt/content1
Type=ext4
Options=noatime

[Install]
WantedBy=multi-user.target

第 2 步:重新加载 systemctl

systemctl daemon-reload

最后步骤:

您现在可以在专用于和的新“服务”上发布start/ 。这不会在重新启动时自动挂载,如果您需要启用该服务来执行此操作。stopmountunmount

systemctl start mnt-content1.mount
systemctl stop mnt-content1.mount

文章:https ://www.golinuxcloud.com/mount-filesystem-without-fstab-systemd-rhel-8/

于 2020-05-27T19:55:33.677 回答