Unix shells: 如何确保命令在大多数常见的 shell 中都能正常运行?

huangapple go评论90阅读模式
英文:

Unix shells: How to ensure command works against most common shells?

问题

我有一些Java代码,使用jsch连接到我们的Unix服务器并运行以下命令。

> ls -lt /tempdirectory/ grep -v '^do | grep "$(date '+%b %e')"' | head
> -1 | awk '{print %9}';

上述命令以长格式显示/tempdirectory/中的所有文件(第一个管道删除目录)。然后,它会从结果中筛选出今天创建的所有文件(即使用grep搜索"Oct 16")。由于我执行了ls -lt,文件按时间排序,因此当我与head -1进行管道连接时,我将获得今天最新的文件。然后,最后一个管道将打印出文件名。

在普通的PuTTY终端上,一旦我切换到bash shell,并运行上述命令,它将正确地打印出今天最新的文件。

但默认的shell似乎是Bourne(-sh),在该shell中,上述命令将失败(因此我的代码也会失败)。

是否有一种方法可以创建适用于常见shell的上述命令?我认为我在工作中看到的主要shell有:

Bourne(sh)
Bourne Again(bash)
Korn(ksh)
英文:

I have some java code which uses jsch to connect to our unix servers and run below command.

> ls -lt /tempdirectory/ grep -v '^do | grep "$"(date '+%b %e')" | head
> -1 | awk '{print %9}'

Above command shows all files in the /tempdirectory in long format (the first pipe removes directories). From the result it then filters for all files which were created today (I.e. it greps for "Oct 16"). Since I did ls -lt the files are ordered by time, so when I pipe against head -1 I will get the latest file today. And then the last pipe will print the filename out

On a normal putty terminal, once I switch to bash shell, and run above command, it will correctly print out the latest file today.

But the default shell seems to be Bourne (-sh) which the above command will fail (and hence my code will fail)

Is there a way to create above command that is safe for common shells? I think the main shells I've seen at work are:

Bourne (sh)
Bourne again (bash)
Korn (ksh)

答案1

得分: 1

这是您应该使用 find(1) 命令的地方:

$ find /tmpdir -type f -ctime -1 

将会获取所有从 /tmpdir 中在今天创建的文件。

如果您想获取所有文件,那么就不需要添加其他修饰符。如果您想进一步限制,请参阅 GNU Find 的手册,链接:https://linux.die.net/man/1/find。

find(1) 命令与您在远程机器上可以访问的 shell 无关。

英文:

This is where you should be using the find(1) command instead:

$ find /tmpdir -type f -ctime -1 

gets all the files from /tmpdir created (ctime) today.

If you want all the files then you don't need any more modifiers. If you want to limit further, see the GNU Find manpage at https://linux.die.net/man/1/find.

The find(1) command is independent of which shell you have access to on the remote machine.

答案2

得分: 0

你贴出的代码

> ls -lt / grep -v '^do | grep "$"(date '+%b %e')" | head -1 |awk'{print %9}'

存在语法错误,无法在任何 shell 中运行。

已修正为

 ls -lt  /tempdirectory/ | grep -v '^d' | grep "$(date '+%b %e')" | head -1 | awk '{print $9}'

这是与 ANSI 兼容的,可以在 shbashzsh(经过我测试)中运行。

英文:

The code that you posted

> ls -lt / grep -v '^do | grep "$"(date '+%b %e')" | head -1 |awk'{print %9}'

has syntax errors and cannot be run in any shell

Fixed it to

 ls -lt  /tempdirectory/ | grep -v '^d' | grep "$(date '+%b %e')" | head -1 | awk '{print $9}'

It is ANSI compatible and runs in sh, bash and zsh (what I have tested).

答案3

得分: 0

根据评论,我找到了问题。Bourne 不能处理 $(...),因此我需要将其替换为 --> ` <---(不是常规的撇号)

参考链接:
https://www.unix.com/shell-programming-and-scripting/188983-syntax-error-line-24-unexpected.html

因此,命令变为

> ls -lt /tempdirectory/ | grep -v '^d' | grep "date &#39;+%b %e&#39;" | head -1 | awk '{print $9}'

我不确定这是否适用于许多不同的 shell,但在 sh 和 bash 上似乎有效。

由于某种原因,StackOverflow 没有正确显示那个撇号,所以我将在以下内容中进行澄清,在第一个双引号之后、最后一个双引号之前,我添加了奇怪的其他撇号 `:

"{此处}date '+%b %e'{此处}"

(另外根据之前的评论,这似乎不仅仅是在确定命令兼容性时使用的 shell 问题——您的底层操作系统也可能会产生影响。在我这个案例中,使用 uname -a 显示我正在使用 sunOS。)

英文:

As per comments, I found the issue. Bourne cannot handle $(...) hence I needed to replace this with --> ` <--- (not the regular apostrophes)

Reference:
https://www.unix.com/shell-programming-and-scripting/188983-syntax-error-line-24-unexpected.html

So the command becomes

> ls -lt /tempdirectory/ | grep -v '^d' | grep "date &#39;+%b %e&#39;" | head -1 | awk '{print $9}'

I dont whether this will work on many different shells but it seems to work on sh as well as bash

For some reason StackOverflow is not showing that apostrophe properly so I will clarify that I added the weird other apostrophe ` after the first double quote and before the last double quote in:

"{here}date '+%b %e'{here}"

(Also based on previous comments, it sounds like this is not just a matter of what shell you are using when determining command compatibility - your underlying OS may also have an impact. In my case, using uname -a shows i am using sunOS)

huangapple
  • 本文由 发表于 2020年10月16日 09:40:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/64381816.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定