Shell变量定义和替换在单行中正确引用?

时间:2013-04-14 13:30:05

标签: bash zsh

我想用以下内容替换查​​询中的一些字符串:

URL="sub.domain.tld" mysql -A --user=username --password="password" --host=hostname usernameuction -e "update core_config_data SET value = 'http://${URL}/' WHERE path LIKE 'web/unsecure/base_url'; update core_config_data SET value = 'https://${URL}/' WHERE path LIKE 'web/secure/base_url';"

此ALMOST完美无缺,但我必须向其添加导出才能使其正常工作:

export URL="sub.domain.tld"; mysql -A --user=username --password="password" --host=hostname usernameuction -e "update core_config_data SET value = 'http://${URL}/' WHERE path LIKE 'web/unsecure/base_url'; update core_config_data SET value = 'https://${URL}/' WHERE path LIKE 'web/secure/base_url';"

如何在没有导出的情况下使这个工作,同时保持var与bash或zsh中引用的命令在同一行?

2 个答案:

答案 0 :(得分:2)

您可以使用unset从您的环境中删除导出的名称。就这样:

export URL=sub.domain.tld; mysql ...; unset URL

$ export FOO=bar; echo $FOO; unset FOO
bar
$ echo $FOO

此外,您可以在子shell中执行一个衬垫:

$ (export FOO=bar; echo $FOO)
bar
$ echo $FOO

您所寻求的是行为,就像执行命令时一样。像这样:

/* foo.c */
main (void)
{ printf ("FOO: %s\n", getenv("FOO")); }

$ FOO=bar ./foo
FOO: bar

通过FOO扩展了对foo的调用的环境。但是,在您的情况下,当处理您的mysql参数时,环境不会被扩展,缺少使用export。你可以使用shell函数:

$ foo () { echo "FOO: ${FOO}"; }
$ FOO=baz foo
FOO: baz
$ echo $FOO

答案 1 :(得分:2)

丢失export,但在变量定义和mysql命令之间保留分号:

URL="sub.domain.tld"; mysql -A --user=username --password="password" --host=hostname usernameuction -e "update core_config_data SET value = 'http://${URL}/' WHERE path LIKE 'web/unsecure/base_url'; update core_config_data SET value = 'https://${URL}/' WHERE path LIKE 'web/secure/base_url';"

说明:当您将变量定义作为单独的命令(例如URL="sub.domain.tld"; mysql ...)给出时,变量在shell中定义并在解析所有后续命令(如mysql ...)时应用,但是不会导出到这些命令的环境。这就是你想要的。

导出变量时(例如export URL="sub.domain.tld"; mysql ...),变量在shell中定义,并在解析后续命令时应用,将导出到这些命令的环境中。

当您将变量定义作为命令的前缀(例如URL="sub.domain.tld" mysql ...)时,它根本不会在shell中设置变量,而是将其导出到该命令的环境中。这根本不适用于您的情况,因为mysql ... "... https://${URL}/ ..."的参数由shell扩展,而不是mysql,您需要在shell中定义的变量,而不是mysql的环境。