podman: Podman --tty breaks pipelines while docker does not

Update

This issue was initially opened with the idea I was hitting a bug in Podman, it turned out that CRLF is set by the TTY (probably from the kernel), and the same behavior can be experienced with Docker as well. Moving further with some tests I found that Podman misbehaves when pipes are involved, while Docker correctly handles them. For a quick sum up jump to https://github.com/containers/podman/issues/9718#issuecomment-799925847, avoiding all the tests which brought me there.


/kind bug

Description

Whenever I run podman container exec/run --tty [...] the output use CRNL (0x0d, 0x0a) instead a simple NL (0x0a) at the end of each output line on Linux.

Steps to reproduce the issue:

  1. podman container run -d --name test alpine:latest sleep infitely
  2. podman container exec -t test echo a | od -c
0000000   a  \r  \n
0000003
  1. podman container exec test echo a | od -c (without --tty)
0000000   a  \n
0000002

same issue with run:

  1. podman container run --rm -t alpine:latest echo a | od -c
0000000   a  \r  \n
0000003

I also test it directly via runc

and I doubt it’s runc fault, as was suggested https://github.com/containers/podman/issues/3179#issuecomment-494783055: runc exec -t c45fa68707ef26672b545a9fc6c317f1b48b5bc5f2df2c9bec22a7eac3339604 echo a | od -c

0000000   a  \n
0000002

podman container exec -t c45fa68707ef26672b545a9fc6c317f1b48b5bc5f2df2c9bec22a7eac3339604 echo a | od -c

0000000   a  \r  \n
0000003

Describe the results you expected:

I’m expecting to only get \n at the end of each output line in Linux.

Additional information:

Output of podman version:

Version:      3.0.1
API Version:  3.0.0
Go Version:   go1.16
Git Commit:   c640670e85c4aaaff92741691d6a854a90229d8d
Built:        Sun Feb 21 16:29:46 2021
OS/Arch:      linux/amd64

Output of podman info --debug:

host:
  arch: amd64
  buildahVersion: 1.19.4
  cgroupManager: cgroupfs
  cgroupVersion: v1
  conmon:
    package: /usr/bin/conmon is owned by conmon 1:2.0.26-1
    path: /usr/bin/conmon
    version: 'conmon version 2.0.26, commit: 0e155c83aa739ef0a0540ec9f9d265f57f68038b'
  cpus: 8
  distribution:
    distribution: manjaro
    version: unknown
  eventLogger: journald
  hostname: wintermute
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1001
      size: 1
    - container_id: 1
      host_id: 10000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 10000
      size: 65536
  kernel: 5.10.19-1-MANJARO
  linkmode: dynamic
  memFree: 8877490176
  memTotal: 33389625344
  ociRuntime:
    name: runc
    package: /usr/bin/runc is owned by runc 1.0.0rc93-1
    path: /usr/bin/runc
    version: |-
      runc version 1.0.0-rc93
      commit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
      spec: 1.0.2-dev
      go: go1.15.7
      libseccomp: 2.5.1
  os: linux
  remoteSocket:
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    selinuxEnabled: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: /usr/bin/slirp4netns is owned by slirp4netns 1.1.9-1
    version: |-
      slirp4netns version 1.1.9
      commit: 4e37ea557562e0d7a64dc636eff156f64927335e
      libslirp: 4.4.0
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.1
  swapFree: 9446825984
  swapTotal: 9446825984
  uptime: 19h 46m 9.72s (Approximately 0.79 days)
registries:
  search:
  - docker.io
store:
  configFile: /home/crazybyte/.config/containers/storage.conf
  containerStore:
    number: 1
    paused: 0
    running: 1
    stopped: 0
  graphDriverName: overlay
  graphOptions:
    .mount_program:
      Executable: /usr/bin/fuse-overlayfs
      Package: /usr/bin/fuse-overlayfs is owned by fuse-overlayfs 1.4.0-1
      Version: |-
        fusermount3 version: 3.10.2
        fuse-overlayfs: version 1.4
        FUSE library version 3.10.2
        using FUSE kernel interface version 7.31
  graphRoot: /home/crazybyte/.local/share/containers/storage
  graphStatus:
    Backing Filesystem: extfs
    Native Overlay Diff: "false"
    Supports d_type: "true"
    Using metacopy: "false"
  imageStore:
    number: 34
  runRoot: /run/user/1000/containers
  volumePath: /home/crazybyte/.local/share/containers/storage/volumes
version:
  APIVersion: 3.0.0
  Built: 1613921386
  BuiltTime: Sun Feb 21 16:29:46 2021
  GitCommit: c640670e85c4aaaff92741691d6a854a90229d8d
  GoVersion: go1.16
  OsArch: linux/amd64
  Version: 3.0.1

Package info (pacman -Qii podman):

Name            : podman
Version         : 3.0.1-2
Description     : Tool and library for running OCI-based containers in pods
Architecture    : x86_64
URL             : https://github.com/containers/libpod
Licenses        : Apache
Groups          : None
Provides        : None
Depends On      : cni-plugins  conmon  containers-common  device-mapper  iptables  libseccomp  runc  slirp4netns  libsystemd  fuse-overlayfs  libgpgme.so=11-64
Optional Deps   : podman-docker: for Docker-compatible CLI
                  btrfs-progs: support btrfs backend devices [installed]
                  catatonit: --init flag support
                  crun: support for unified cgroupsv2
Required By     : None
Optional For    : None
Conflicts With  : None
Replaces        : None
Installed Size  : 75.64 MiB
Packager        : Morten Linderud <foxboron@archlinux.org>
Build Date      : Sun 21 Feb 2021 04:29:46 PM CET
Install Date    : Mon 01 Mar 2021 09:40:58 AM CET
Install Reason  : Explicitly installed
Install Script  : No
Validated By    : Signature
Backup Files    :
(none)

Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide?

Yes

Additional environment details (AWS, VirtualBox, physical, etc.): I’m using Manjaro Linux, zsh (v. 5.8) and Tmux (v. 3.1c)

stty -a (zsh on my host system)

speed 38400 baud; rows 74; columns 189; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

podman container exec -t c45fa68707ef26672b545a9fc6c317f1b48b5bc5f2df2c9bec22a7eac3339604 stty -a

speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke -flusho -extproc

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 31 (14 by maintainers)

Commits related to this issue

Most upvoted comments

During a very pleasant chat with @giuseppe over IRC, he helped me to implement his suggestion to my context and it works great! Drop the solution here for the record and hoping it will help others who will struggle with the same issue in the future.

podman_run () {
    _ti="-ti"; tty 0<&1 &>/dev/null || _ti=""
    podman container run --rm $_ti alpine:latest "$@"
}

> podman_run echo | cat -A
$
> 

Feel free to close this issue if this workaround is considered enough, for me it is.

In this related Docker issue: https://github.com/moby/moby/issues/37366#issuecomment-401157643 it is stated that this is not a bug. The carriage return is added by the TTY (not Docker). I guess the situation is the same for Podman.