在多个Shell脚本中执行相同的命令

时间:2021-07-02 21:33:55

I'm using the following to to tee output of a command into a file:

我正在使用以下内容将命令输出到文件中:

logs/`basename $0`-`basename $1`.`date +%F--%R\`.log

And since this same syntax belongs in several different shell scripts, I'd really like it to only appear once. My first thought was to put it in another shell script:

由于这个语法属于几个不同的shell脚本,我真的希望它只出现一次。我的第一个想法是把它放在另一个shell脚本中:

export LOGFILE=logs/`basename $0`-`basename $1`.`date +%F--%R`.log
# OR
export LOGFILE=logs/\`basename $0\`-\`basename $1\`.\`date +%F--%R\`.log

And have each file call the command like this:

并让每个文件调用这样的命令:

java CMD | tee $LOGFILE

However this doesn't work. Is there any way to describe a file to create in the way you see above only once but be able to reference it repeatedly in scripts?

但这不起作用。有没有办法以上面看到的方式描述要创建的文件,但能够在脚本中重复引用它?

4 个解决方案

#1


One solution is to define a function in the shell script...

一种解决方案是在shell脚本中定义一个函数......

But you almost have it working with the export. If you want to keep going with that, the key is to escape out the $'s so they don't get replaced with their values until you're ready. Then use eval to re-evaluate it later.

但你几乎让它与出口合作。如果你想继续这样做,关键是要逃避$,所以在你做好准备之前,他们不会被他们的价值取代。然后使用eval稍后重新评估它。

E.g.:

501 ~$ export foo='$bar'
502 ~$ echo $foo
$bar
503 ~$ export bar=moo
504 ~$ eval echo $foo
moo
505 ~$ export bar=hello
506 ~$ eval echo $foo
hello

#2


If your shell supports defining functions (e.g., bash, korn, etc.) then you could put it in a function and have each script include/import/whatever that file that the function is in.

如果你的shell支持定义函数(例如bash,korn等),那么你可以将它放在一个函数中,让每个脚本都包含/ import /该函数所在的文件。

#3


The reason that exporting the LOGFILE variable does not work, is that $0 and $1 don't have useful values at that point ($0 is probably your shell's executable, and $1 is probably nothing). One possibility would be a wrapper script like this:

导出LOGFILE变量不起作用的原因是$ 0和$ 1在那时没有有用的值($ 0可能是你的shell的可执行文件,$ 1可能没什么)。一种可能性是这样的包装脚本:

#!/bin/sh
LOGFILE="logs/`basename $0`-`basename $1`.`date +%F--%R`.log"
"$@" | tee "$LOGFILE"

Anything that you would otherwise pipe to tee, you now pass as arguments to the wrapper script. For example (assuming it was named new-tee) new-tee java CMD or for testing, new-tee echo "hello world".

否则你将管道发送到tee,你现在作为参数传递给包装器脚本。例如(假设它被命名为new-tee)new-tee java CMD或用于测试,new-tee echo“hello world”。

#4


After examining my specific curcumstances further, I think the best thing I can do is stop using bash and upgrade to a more powerful scripting language like Python. Ethan's answer does indicate my problem can be resolved in Bash, but I would suggest to anyone looking to do what I'm doing that they examine if there's not a simpler way to do what they're doing, or if their problem might be better handled in Python.

在进一步检查我的具体情况后,我认为我能做的最好的事情就是停止使用bash并升级到更强大的脚本语言,如Python。 Ethan的回答确实表明我的问题可以在Bash中得到解决,但我建议任何想要做我正在做的事情的人,他们会检查是否有更简单的方法去做他们正在做的事情,或者他们的问题可能会更好用Python处理。

#1


One solution is to define a function in the shell script...

一种解决方案是在shell脚本中定义一个函数......

But you almost have it working with the export. If you want to keep going with that, the key is to escape out the $'s so they don't get replaced with their values until you're ready. Then use eval to re-evaluate it later.

但你几乎让它与出口合作。如果你想继续这样做,关键是要逃避$,所以在你做好准备之前,他们不会被他们的价值取代。然后使用eval稍后重新评估它。

E.g.:

501 ~$ export foo='$bar'
502 ~$ echo $foo
$bar
503 ~$ export bar=moo
504 ~$ eval echo $foo
moo
505 ~$ export bar=hello
506 ~$ eval echo $foo
hello

#2


If your shell supports defining functions (e.g., bash, korn, etc.) then you could put it in a function and have each script include/import/whatever that file that the function is in.

如果你的shell支持定义函数(例如bash,korn等),那么你可以将它放在一个函数中,让每个脚本都包含/ import /该函数所在的文件。

#3


The reason that exporting the LOGFILE variable does not work, is that $0 and $1 don't have useful values at that point ($0 is probably your shell's executable, and $1 is probably nothing). One possibility would be a wrapper script like this:

导出LOGFILE变量不起作用的原因是$ 0和$ 1在那时没有有用的值($ 0可能是你的shell的可执行文件,$ 1可能没什么)。一种可能性是这样的包装脚本:

#!/bin/sh
LOGFILE="logs/`basename $0`-`basename $1`.`date +%F--%R`.log"
"$@" | tee "$LOGFILE"

Anything that you would otherwise pipe to tee, you now pass as arguments to the wrapper script. For example (assuming it was named new-tee) new-tee java CMD or for testing, new-tee echo "hello world".

否则你将管道发送到tee,你现在作为参数传递给包装器脚本。例如(假设它被命名为new-tee)new-tee java CMD或用于测试,new-tee echo“hello world”。

#4


After examining my specific curcumstances further, I think the best thing I can do is stop using bash and upgrade to a more powerful scripting language like Python. Ethan's answer does indicate my problem can be resolved in Bash, but I would suggest to anyone looking to do what I'm doing that they examine if there's not a simpler way to do what they're doing, or if their problem might be better handled in Python.

在进一步检查我的具体情况后,我认为我能做的最好的事情就是停止使用bash并升级到更强大的脚本语言,如Python。 Ethan的回答确实表明我的问题可以在Bash中得到解决,但我建议任何想要做我正在做的事情的人,他们会检查是否有更简单的方法去做他们正在做的事情,或者他们的问题可能会更好用Python处理。