模拟文件的进程替换

模拟文件的进程替换

我不记得如何实现这一点,我试图支持用户能够在其命令中包含纯文本以供临时使用:

这里它从文件 file.json 读取:

lp_solve --method='simplex' --problem='<file.json>'

但我希望用户能够使用进程替换来内联编写 json:

lp_solve --method='exhaustive' --problem=<(echo '
   {"foo":"bar","this":"is json"}
')
 

这可以跨平台吗?我需要在“<()”两边加引号吗?

答案1

假设 shell 是 bash、zsh 或 ksh93 的最新版本,并且该功能在构建时尚未禁用,

lp_solve --method='simplex' --problem=<(echo 'something')

lp_solve使用其最后一个参数进行调用--problem=/path/to/some/file,其中/path/to/some/file标识管道的读取端。要么/dev/fd/n是原始的 ksh 实现,要么是命名管道或/proc/self/fd/n.

其他 shell 要么不支持进程替换,要么使用不同的语法支持它(<{cmd}在类似 rc 的 shell 中,(cmd | psub)在 中fish)和/或<(cmd)用于其他用途(例如在 中进行进程重定向yash<在重定向后进行命令替换fish

该文件是管道的事实有几个含义,这意味着它不能总是用作常规文件的一对一替换:

  • 应用程序(此处lp_solve)无法在文件内查找
  • 如果应用程序在读取一次后再次打开它,它将显示为空。
  • 尝试写入文件将失败或无法按预期工作

zsh 和 Fish 具有使用临时常规文件的进程替换形式:

  • ... --problem==(echo '...')(zsh)
  • ... --problem=(echo '...' | psub -f)(鱼)

"$(echo ... | psub)"除了最新版本的之外fish,进程替换不在引号内执行,因此您可以不是想在这些周围使用引号。

请记住,echo即使在 bash 中也不能可移植地用于任意文本,特别是不能用于包含\字符的文本(在 json 中常见)。您可能想改用printf

这里除了有一个--problem以文件作为参数的 ,你还可以有一个以 json 字符串为参数的。喜欢--problem-file=file.json--problem='{"some": "json"}'。或者,由于 json 字符串不能以 开头@,因此curl对其某些选项和、有--problem='{"some": "json"}'和执行类似操作[email protected]


1 进程替换来自 80 年代中期的 ksh,但仅在有/dev/fd/n支持的系统上可用,并且扩展不能成为参数的一部分,--problem <(cmd)本来可以工作,但不行--problem=<(cmd)(直到一些相对较新的 ksh93 版本之前仍然如此)

configure² 在 bash 中,如果使用--disable-process-substitution或调用脚本,则禁用进程替换--enable-minimal-config

答案2

笔记

我注意到这lp_solve是一个数学程序,因此下面的代码将无法按您想要的方式工作。这是因为程序需要一个路径名。


当您使用进程替换时,您应该读取从标准输入传递给脚本的内容(我认为它就像一个管道)。

现在,如果lp_solve是自定义编程/shell 脚本(例如 bash),那么您应该使用以下内容来读取标准输入:

#!/usr/bin/bash
echo Data:
cat

要通过stdin你应该使用:

lp_solve --method='simplex' --problem=< <(echo Fuzz)
#Output:
Data:
Fuzz

但是,正如您在上面看到的,它< <(echo Fuzz)被视为stdin而不是作为参数,因此您将无法读取任何$N变量。

如果您想作为参数传递给脚本,您应该使用:

lp_solve --method='simplex' --problem='
{"foo":"bar","this":"is json"}
{"foo":"buzz","this":"is json"}
{"foo":"foo","this":"is json"}
etc...
'

当您键入时,lp_solve --method='simplex' --problem='您应该按 Enter 才能完全的你的字符串。
顺便说一句,使用时要小心,--problem='因为如果您键入'字符串就会完成。例如:

lp_solve --method='simplex' --problem='
this is a text
this is a'text
#Output:
this is a text
this is atext

如您所见,'已删除。我假设在其他 shell 中,行为可能有所不同,或者脚本可能会失败。

相关内容