尝试在 Bash shell 中运行函数会产生意想不到的结果

Posted

技术标签:

【中文标题】尝试在 Bash shell 中运行函数会产生意想不到的结果【英文标题】:Trying to run a function in the Bash shell gives unexpected results 【发布时间】:2021-08-12 08:20:14 【问题描述】:

我一直在尝试使用命令行中的 libreoffice 将一堆非常旧的 MS Office 文件批量转换为 odf 格式以用于存档目的。为此,我首先将所有文件收集在一个目录中,然后在所述目录中调用以下命令(用于 doc 文件):

/path/to/soffice --headless --convert-to odt *doc

这很好用,该命令会一次性转换目录中的所有 doc 文件。但是,我想避免总是用必要的参数输入soffice 的路径,所以我在我的 Bash 配置文件中添加了以下内容:

alias libreconv='function _libreconv() /path/to/soffice --headless --convert-to "$1" "$2"; ; _libreconv'

但是,当我现在尝试调用以下内容时:

libreconv odt *doc

这只会导致目录中的第一个 doc 文件被转换,之后函数退出并返回提示...也许我遗漏了一些明显的东西(毕竟我是一个 cli 新手),但我确实这样做了不明白为什么当我直接运行soffice 命令时,调用该函数会导致只转换第一个文件而不是所有文件。

在此先感谢您提供的帮助,帮助我了解这里出了什么问题。 :)

【问题讨论】:

使用别名定义函数有什么意义???? @user1934428 在某些情况下可能有一些模糊的理由这样做,但在这种情况下,它可能是初学者反模式的货物崇拜副本。请参阅我在回答中链接到的问题以进行一些讨论。 【参考方案1】:

因为你的函数只接受两个参数。

可能不会硬编码到soffice 的路径;相反,请确保您的 PATH 包含它的安装目录。

无论如何,别名在这里完全没用;另见Why would I create an alias which creates a function?

如果你想创建一个函数,试试类似

libreconv ()  soffice --headless --convert-to "$@"; 

"$1""$2" 参数实际上扩展为前两个参数。参数"$@" 扩展到所有参数,保留引号(如果您想处理带有空格的文件名等,这很重要;您会看到许多脚本错误地使用了"$*"$@ 而没有引号)。

如果soffice 位于您不希望在PATH 中的奇怪位置,请在PATH 的目录中添加符号链接。一种常见的安排是使用~/bin 并使用指向奇怪二进制文件的符号链接填充它,其中可能包括您自己的脚本,这些脚本安装在某个地方的 Git 工作目录中用于开发。

.bash_profile 或类似的常用咒语是

if [[ -d ~/bin ]]; then
    case :$PATH: in
     *:~/bin:* | *:$HOME/bin:* ) ;;
     *) PATH=~/bin:$PATH;;
    esac
fi

这样,您可以(如果不存在则创建~/binmkdir ~/bin)和ln -s /path/to/soffice ~/bin 来创建指向真实位置的符号链接。

【讨论】:

以上是关于尝试在 Bash shell 中运行函数会产生意想不到的结果的主要内容,如果未能解决你的问题,请参考以下文章

R 用 lubridate 在 DST 上添加月份会产生意想不到的结果

如何在从我产生的工作中获取一行标准输出时阻止 bash

使用 Javascript 设置元素的宽度会产生意想不到的结果

在 while 循环中使用 -- 运算符会产生意想不到的结果

如何将 shell 设置为 bash 以在 Capistrano 中运行?

在 Axios 请求上使用 Lodash 的 Debounce 会产生意想不到的结果