Opened 14 years ago
Closed 12 years ago
#42 closed enhancement (fixed)
don't read stdin when running in a noninteractive shell
Reported by: | taeuber | Owned by: | |
---|---|---|---|
Priority: | wish | Component: | ffmpeg |
Version: | git | Keywords: | noninteractive shell stdin |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | yes | |
Analyzed by developer: | yes |
Description
ffmpeg reads stdin also when on a noninteractive shell:
See: https://lists.ffmpeg.org/pipermail/ffmpeg-user/2011-April/000252.html
Or is the reason for this behaviour a different one?
Thanks
Change History (11)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Hi michael,
I'm not sure but this seems to be it:
$ man 4 tty
$ man tcgetpgrp
$ man getpgid
int am_I_interactive()
{
int fd = open ("/dev/tty", O_RDONLY);
int interactive = (tcgetpgrp(fd) == getpgid());
close (fd);
return interactive;
}
This is stolen from:
http://www.perlmonks.org/?node_id=472070
I understand this as following:
If I'm the process group leader I am interactive otherwise I'm noninteractive. (only on posix systems)
Thanks
Lars
comment:3 by , 13 years ago
Owner: | removed |
---|---|
Status: | new → open |
Now someone just needs to add checks for errors (like file not found) and configure checks for the posix functions unless they are available everywhere.
And thanks for the hint.
comment:4 by , 13 years ago
Hi Michael,
this is how I would implement it:
int interactive() { int fd, interactive; fd = open ("/dev/tty", O_RDONLY); if (fd < 0) return fd; interactive = (tcgetpgrp(fd) == getpgid(0)); close (fd); return interactive; }
I have no idea about autoconf tools.
But this doesn't solve the problem. It only tests foreground or background processing.
Maybe an additional command line option would be the solution of choice?
Lars
follow-up: 6 comment:5 by , 13 years ago
Hi Michael,
i found the correct solution:
inline int interactive() { return isatty(0); }
When STDIN is a terminal it is interactive otherwise not.
Yes, so simple!!
Best regards
Lars
follow-up: 7 comment:6 by , 13 years ago
Replying to taeuber:
Hi Michael,
Hi lars
i found the correct solution:
inline int interactive() { return isatty(0);
i wish it was so simple
but isatty is true for a command like
ffmpeg -i abc.avi def.avi &
and that will then still get stuck without </dev/null
comment:7 by , 13 years ago
Replying to michael:
Replying to taeuber:
Hi Michael,
Hi lars
i found the correct solution:
inline int interactive() { return isatty(0);i wish it was so simple
but isatty is true for a command like
ffmpeg -i abc.avi def.avi &
and that will then still get stuck without </dev/null
In this case we should check for being a foreground process.
I think this is what my first solution does:
int foreground_process() { int fd, foreground; fd = open ("/dev/tty", O_RDONLY); if (fd < 0) return fd; foreground = (tcgetpgrp(fd) == getpgid(0)); close (fd); return foreground; }
Lars
comment:8 by , 13 years ago
We need to check for being a foreground process only if we are an interactive process.
int accept_stdin_commands = 0; if interactive() if foreground_process() accept_stdin_commands = 1;
But being a foreground process can change during execution!
So we should expect the user to be smart enough to know the implications about background processes.
Lars
follow-up: 10 comment:9 by , 13 years ago
This is crazy, internets are full of question how to disable this flaming interactive mode, and years thru, it's still not solved, and now there's discussion "how to detect it". Being smarter than a user is highly optional, so just let user tell what one wants with -non-interactive. Don't forget that being non-interactive means not only not reading from stdin, but also not outputting that stupid progress indicator which otherwise doesn't allow to capture clean and nice log, and instead non-deterministically intersperses itself with it:
[mpeg1video @ 0x813c710]ac-tex damaged at 21 17 [mpeg1video @ 0x813c710]Warning MVs not available [mpeg1video @ 0x813c710]concealing 22 DC, 22 AC, 22 MV errors frame= 932 fps= 0 q=0.0 size= -0kB time=37.28 bitrate= -0.0kbits/s dup=1 drop=0 ^M[mpeg1video @ 0x813c710]Warning MVs not a [mpeg1video @ 0x813c710]concealing 22 DC, 22 AC, 22 MV errors frame= 1841 fps=1839 q=0.0 size= -0kB time=73.64 bitrate= -0.0kbits/s dup=1 drop=0 ^M[mpeg1video @ 0x813c710]ac-tex damaged a
Thanks for thinking with perspective on how users can use your software!
comment:10 by , 13 years ago
Replying to pfalcon:
This is crazy, internets are full of question how to disable this flaming interactive mode, and years thru, it's still not solved, and now there's discussion "how to detect it". Being smarter than a user is highly optional, so just let user tell what one wants with -non-interactive.
The -d option (run as daemon) might be what you are looking for.
comment:11 by , 12 years ago
Analyzed by developer: | set |
---|---|
Reproduced by developer: | set |
Resolution: | → fixed |
Status: | open → closed |
Should be addressed in:
commit 0fe8acf2d69bf4bce620128e48b62a957421a106 Author: Nicolas George <nicolas.george@normalesup.org> Date: Wed Jul 11 21:10:17 2012 +0200 ffmpeg: add -(no)stdin option. Allows to disable interaction from standard input. Useful, for example, if ffmpeg is in the background process group. Roughly the same result can be achieved with "ffmpeg ... < /dev/null" but it requires a shell.
The -nostdin option will disable reading from stdin mode, and seems more robust than try to be more clever than the user and auto-detect interactive mode.
Together with -nostats should allow what pfalcon asks.
If someone tells me how to detect "running in a noninteractive shell" halfway portably then this is
trivial to implement