Quando ls
viene chiamato, restituisce tutti i file/directory nella directory corrente, cercando di adattarne il maggior numero possibile su ciascuna riga. Perché è passato a wc -l
, restituisce il numero di file? Come fa a decidere in quante righe emettere i suoi risultati?
Risposta accettata:
Quando ls
viene eseguito analizza varie opzioni. Rileva anche se l'output è un tty o meno da isatty().
ls.c:
codice
case LS_LS:
/* This is for the `ls' program. */
if (isatty (STDOUT_FILENO))
{
format = many_per_line;
/* See description of qmark_funny_chars, above. */
qmark_funny_chars = true;
}
else
{
format = one_per_line;
qmark_funny_chars = false;
}
break;
…
codice
/* disable -l */
if (format == long_format)
format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
ecc.
Se vuoi puoi compilare un semplice test:
isawhat.c
#include <stdio.h>
#include <unistd.h>
int main(void)
{
if (isatty(STDOUT_FILENO)) {
fprintf(stdout, "Word by word my world.n");
} else {
fprintf(stdout, "HELP! Stranger handling my words!!n");
}
fprintf(stderr, "Bye bye.n");
return 0;
}
Compila per:
gcc -o isawhat isawhat.c
Quindi ad es.:
$ ./isawhat | sed 's/word/world/'
La larghezza è misurata in colonne. Una colonna è un carattere. Inizia con 80, quindi controlla se la variabile d'ambiente COLUMNS è impostata e contiene un int valido che non è maggiore di SIZE_MAX (che dipende dall'arco:il tuo terminale non sarà mai così largo (almeno non ancora)).
Prova ad es. echo $COLUMNS
. Molto probabilmente riflette il numero di colonne disponibili nella finestra. Man mano che la finestra viene ridimensionata, questa viene aggiornata. Molto probabilmente viene ripristinato anche da vari comandi.
Un modo per impostarlo un po' più difficile è con stty
. Per esempio. stty columns 60
. Usa stty -a
per visualizzare tutto (man stty). Un software divertente.
Se compilato in esso, interroga anche le colonne tramite ioctl(), Window size detection.. Passando il filenumber per stdout a ioctl
e passando la richiesta TIOCGWINSZ alla struttura winsize
riempi con il numero di colonne.
Questo può essere dimostrato anche da un semplice c-code:
Compila, esegui e ridimensiona la finestra. Dovrebbe aggiornare. Ctrl+C per uscire.
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <signal.h>
static int run;
void sig_handler(int sig) {
switch (sig) {
case SIGINT:
case SIGTERM:
case SIGSTOP:
run = 0;
break;
}
}
void sig_trap(int sig) {
if ((signal(sig, sig_handler)) == SIG_IGN)
signal(sig, SIG_IGN);
}
int main(void)
{
struct winsize ws;
sig_trap(SIGINT);
sig_trap(SIGTERM);
sig_trap(SIGSTOP);
run = 1;
while (run) {
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
fprintf(stdout, "r %s: %3d, %s: %dr",
"Columns", ws.ws_col,
"Rows", ws.ws_row
);
fflush(stdout);
}
usleep(5000);
}
fprintf(stdout, "n");
return 0;
}