Próbuję przekazać informacje do programu, który nie przyjmuje danych wejściowych ze standardowego wejścia. Aby to zrobić, używam/dev/stdin jako argumentu, a następnie próbuję potokować w moim pliku wejściowym. Zauważyłem, że jeśli robię to z postacią rury:stdin zachowuje się inaczej po instalacji i przekierowaniu
[[email protected] ernwin]$ cat fess/structures/168d.pdb | MC-Annotate /dev/stdin
Nie otrzymuję danych wyjściowych. Jeśli jednak zrobić to samo przy użyciu lewy znak daszka, to działa dobrze:
[[email protected] ernwin]$ MC-Annotate /dev/stdin < fess/structures/168d.pdb
Residue conformations -------------------------------------------
A1 : G C3p_endo anti
A2 : C C3p_endo anti
A3 : G C3p_endo anti
Moje pytanie brzmi, jaka jest różnica między tymi dwoma procesami i dlaczego dać inny wynik? Jako pytanie dodatkowe, czy istnieje właściwe określenie wprowadzania danych za pomocą symbolu "<"?
Aktualizacja:
Mój obecny najlepszy Domyślam się, że coś się wewnątrz istoty przebiegu programu wykorzystuje szukając w pliku. Poniższe odpowiedzi zdają się sugerować, że ma coś wspólnego ze wskaźnikami ale plik uruchamiając następujące mały program testowy:
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *f = fopen(argv[1], "r");
char line[128];
printf("argv[1]: %s f: %d\n", argv[1], fileno(f));
while (fgets(line, sizeof(line), f)) {
printf("line: %s\n", line);
}
printf("rewinding\n");
fseek(f, 0, SEEK_SET);
while (fgets(line, sizeof(line), f)) {
printf("line: %s\n", line);
}
fclose(f);
}
wskazuje, że wszystko odbywa się identycznie aż do wywołania fseek
funkcji:
[[email protected] tmp]$ cat temp | ./a.out /dev/stdin
argv[1]: /dev/stdin f: 3
line: abcd
rewinding
===================
[[email protected] tmp]$ ./a.out /dev/stdin < temp
argv[1]: /dev/stdin f: 3
line: abcd
rewinding
line: abcd
Korzystanie z podstawienia procesu, jak Christopher Neylan sugeruje, że prowadzi do programu powyżej wiszącego nawet bez czytania wejścia, co również wydaje się trochę dziwne.
[[email protected] tmp]$ ./a.out /dev/stdin <(cat temp)
argv[1]: /dev/stdin f: 3
Patrząc na wyjście strace potwierdza moje podejrzenie, że operacja poszukiwania jest usiłowanie, które nie w wersji rurze:
_llseek(3, 0, 0xffffffffffd7c7c0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
I powiedzie w wersji przekierowania.
_llseek(3, 0, [0], SEEK_CUR) = 0
Morał z historii: nie przypadkowo próbować zastąpić argument z /dev/stdin
i starają się rury do niego. To może zadziałać, ale równie dobrze może nie.
Sprawdź informacje tutaj: http://stackoverflow.com/questions/1312922/detect-if-stdin-is-a-terminal-or-pipe-in-cc-qt – Atle
To interesujące, ale wydaje się, że nie robi takiego czeku. I niezależnie od tego, czy wyjście z isatty() nie powinno być takie samo w obu wymienionych tutaj przypadkach wejściowych? Jest to przeciwieństwo do połączonego wpisu, który nie ma przekierowanych danych wejściowych. –
Zgodnie z drugą odpowiedzią | zwraca TAK dla isatty while
Atle