3

我希望具有与 ls 在 bash 或 python 脚本中创建的相同的输出。我的意思不是列出目录,但 ls 所做的事情是能够“循环”。例子:

# ls
a b c d

# ls | head -n 1
a

# for i in $(ls); do echo "file: $i"; done
file: a
file: b
file: c
file: d

ls 怎么会这样,在调用它时仍然在一行中显示所有内容?

使用制表符不起作用..换行符只是强制它是多行。\000 不起作用。

# echo -e "a\tb\tc\td" | head -n 1
a    b    c    d

echo -e "a\000b\000c\000d" | head -n 1
abcd

cat -A 没有给我太多信息...

# cat -A <(ls --color=no)
a$
b$
c$
d$

# cat -A <(echo -e "a\nb\nc\nd")
a$
b$
c$
d$

所以.. 我怎样才能在我的脚本中生成相同类型的输出?我在这里缺少任何控制字符吗?

4

3 回答 3

8

诀窍是检测输出是否为终端,在这种情况下ls使用列,在这种情况下,它以更简单的格式输出。

在 Unix 中,您应该能够使用 Python 的os.isatty()函数来获取此信息。

在 shell 中,您可以使用该tty(1)程序:tty -s <&1. 如果 stdout 是 tty,这将退出 true,如果不是,则退出 false。tty实际上检查标准输入,但<&1您可以将标准输出重定向到标准输入以有效检查标准输出。

于 2012-05-28T11:35:11.620 回答
4

接受第一个答案,但这是一个完整的例子..

猫测试.py

#!/usr/bin/env python

import os

if os.isatty(1):
    print 'is tty'
else:
    print 'is script'

和输出:

# python test.py
is tty

# python test.py | tail -n 1
is script
于 2012-05-28T11:53:15.637 回答
3

在 Bash 中:

#!/bin/bash
if [[ -p /dev/stdout || ! -t 1 ]]    # output is to a pipe or redirected
then
    printf '%s\n' "$@"
else                                 # output is to the terminal
    printf '%s' "$*"
    printf '\n'
fi

仅供参考:使用for i in *而不是for i in $(ls)

于 2012-05-28T12:21:22.067 回答