在bash脚本中使用'which'命令

3

有时候我看到bash脚本中会出现这样的结构:

MYSQL=`which mysql`
$MYSQL -uroot -ppass -e "SELECT * FROM whatever"

在其他脚本中,命令(在此示例中为mysql)直接使用:

mysql -uroot -ppass -e "SELECT * FROM whatever"

那么,为什么和何时应该使用which?以及对于哪些命令-我从未看到过使用echowhich...
2个回答

4

您可以使用man which来查看详细信息:

DESCRIPTION

   which  returns the pathnames of the files (or links) which would be executed in the current environment,
   had its arguments been given as commands in a strictly POSIX-conformant shell.  It does this by  search‐
   ing  the  PATH  for  executable  files  matching the names of the arguments. It does not follow symbolic
   links.

因此,which mysql 只返回当前 mysql 命令的路径。

然而,在您的示例中使用 which 确保忽略当前环境中设置的任何 mysql 别名。

但是,在 shell 中有另一种聪明的方式可以避免使用 which。您可以使用反斜杠调用 mysql:

\mysql -uroot -ppass -e "SELECT * FROM whatever"

这将与您的两个命令所做的效果基本相同来自OP:使用which的唯一原因是避免与自定义别名(例如alias mysql="mysql -upeter -ppaula")可能出现的问题。而且由于很少有人会为echo设置别名,我们不需要使用echo的这种构造方式。但是为mysql设置别名非常常见(没有人想记忆和输入24个字符长的密码)。

我知道 which 返回该命令的路径。我的问题是,为什么和何时需要它。 which echo 返回 /bin/echo,但没有人在 echo 中使用这种构造。 - AvL
我刚刚更新了你的示例中的一个用例(通过存储“which”命令的输出,它忽略了mysql可能存在的任何别名)。 - anubhava
那么,有没有推荐的最佳实践,应该使用哪些命令与 which 一起使用?我不想在我的 bash 脚本中包含一个带有所有使用 which 包装的命令的 反向别名文件... - AvL
1
抱歉再次打扰您,但是我的问题的答案是: 使用 which 的唯一原因是避免与自定义别名(如 alias mysql="mysql -upeter -ppaula")可能出现的问题。由于很少有人会为 echo 等设置别名,所以我们不需要使用这种 echo 构造。但是为 mysql 设置别名非常常见(没有人想记住并输入长达24个字符的密码)... - AvL
是的,这是一个很好的表达方式,让我把它加到回答中以供其他读者参考。 - anubhava
也许你可以在回答中加入一个支持使用 which 的好用例:在脚本的开头(或者在一个额外的 .config 文件中)加入 MYSQL=\which mysql`,这样用户就可以调用不同于默认安装的 mysql,将 which mysql替换为例如/Applications/XAMPP/xamppfiles/bin/mysql`。 - AvL

1

它们大部分是相同的:

只是which会返回二进制文件的绝对路径。有时候,当你在使用第三方程序执行脚本或准备脚本运行环境时,整个二进制文件路径会很方便。

例如,在调度程序的情况下,如果你已经安排了一个脚本,那么你将需要使用其绝对路径的二进制文件。

因此:

mysql=`which mysql` 

或者

mysql=$(which mysql)

或者甚至

/usr/bin/mysql <flags>

您的计划任务脚本可能已经运行,使用了

标签。
mysql ....<flags> 

但正如前一篇文章所解释的那样,并不是完全保证。别名可能是其中一个原因。 对于未使用绝对路径可能带来的问题,请查看此链接

是的,我也在远程考虑过这个问题。如果脚本例如被 php 调用,则通常需要绝对路径:exec('/usr/local/bin/mysql -uroot -ppass -e "SELECT * FROM whatever"');(当然你不会在 php 中使用 exec 调用 mysql …) - AvL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接