Reputation: 5455
I want to have the same output as ls creates in a bash or python script. I don't mean listing directories, but the thing ls does to be able to be "loopable". Example:
# 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
How can ls be like that and still display everything in one line when calling it?
Using tabs doesn't work.. Newlines just force it to be multiple lines. \000 doesn't work.
# 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 doesn't give me much info...
# cat -A <(ls --color=no)
a$
b$
c$
d$
# cat -A <(echo -e "a\nb\nc\nd")
a$
b$
c$
d$
So.. How can I generate the same type of output does in my scripts? Is there any control characters I am missing here?
Upvotes: 3
Views: 2411
Reputation: 360355
In 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
FYI: use for i in *
instead of for i in $(ls)
Upvotes: 3
Reputation: 399989
The trick is to detect whether the output is a terminal, in which case ls
uses columns, or not, in which case it outputs in a simpler format.
In Unix, you should be able to use Python's os.isatty()
function to get this information.
From the shell, you can use the tty(1)
program: tty -s <&1
. This will exit true if stdout is a tty, and false if it is not. tty
actually checks stdin, but with <&1
you can redirect stdout to stdin to effectively check stdout.
Upvotes: 8
Reputation: 5455
First answer accepted, but here is a complete example..
cat test.py
#!/usr/bin/env python
import os
if os.isatty(1):
print 'is tty'
else:
print 'is script'
And the output:
# python test.py
is tty
# python test.py | tail -n 1
is script
Upvotes: 4