Quand ls
est appelée, elle affiche tous les fichiers/répertoires du répertoire courant, en essayant d'en mettre le plus possible sur chaque ligne. Pourquoi est-ce que lorsqu'il est passé à wc -l
, il affiche le nombre de fichiers ? Comment décide-t-il du nombre de lignes dans lesquelles afficher ses résultats ?
Réponse acceptée :
Quand ls
est exécuté, il analyse diverses options. Il détecte également si la sortie est un tty ou non par isatty().
ls.c:
code
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;
…
code
/* disable -l */
if (format == long_format)
format = (isatty (STDOUT_FILENO) ? many_per_line : one_per_line);
etc.
Si vous le souhaitez, vous pouvez compiler un test simple :
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;
}
Compilé par :
gcc -o isawhat isawhat.c
Alors par exemple :
$ ./isawhat | sed 's/word/world/'
La largeur est mesurée en colonnes. Une colonne correspond à un caractère. Il commence par 80, puis vérifie si la variable d'environnement COLUMNS est définie et contient un int valide qui n'est pas supérieur à SIZE_MAX (qui dépend de l'architecture - votre terminal ne sera jamais aussi large (du moins pas encore)).
Essayez par ex. echo $COLUMNS
. Cela reflète très probablement le nombre de colonnes dont vous disposez dans la fenêtre. Au fur et à mesure que la fenêtre est redimensionnée, elle est mise à jour. Il est très probablement également réinitialisé par diverses commandes.
Une façon de le rendre un peu plus difficile est d'utiliser stty
. Par exemple. stty columns 60
. Utilisez stty -a
pour tout voir (man stty). Un logiciel amusant.
S'il est compilé, interrogez également les colonnes par ioctl(), détection de la taille de la fenêtre. En passant le numéro de fichier pour stdout à ioctl
et en passant la requête TIOCGWINSZ la structure winsize
se remplir du nombre de colonnes.
Cela peut également être démontré par un simple code-c :
Compiler, exécuter et redimensionner la fenêtre. Devrait mettre à jour. Ctrl+C pour quitter.
#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;
}