Вот что это за чёрная магия, а? пытаюсь скормить запрос mysql через stdin - access denied. запускаю рукой - никаких проблем!
нет, это не хитрый алиас. и .my.cnf нету. mysql голимый, из пакета.К решению ведёт размышление "задом наперёд": не "чего это он не коннектится с перенаправлением", а "почему он коннектится без перенаправления — ведь пароль я не говорил".
Пакет mysql-server в дебиане после установки спрашивает пароль для mysql root. При установке из скрипта (в моём случае - из Ansible, который я не устаю пиарить!) спрашивать не у кого, так что root остаётся без пароля. Это стрёмно, но не ужасно: mysql из коробки слушает только 127.0.0.1, так что воспользоваться таким доступом можно только локально.
Дальше дело такое: если клиент mysql запускается без явного указания имени пользователя, то "MySQL clients by default try to log in using the current Unix user name as the MySQL user name" Но вот это вот "current Unix user name" он берёт не из getuid, как можно бы подумать, а из getlogin: https://github.com/facebook/mysql-5.6/blob/webscalesql-5.6.16-47/libmysql/libmysql.c#L420
А getlogin возвращает владельца "controlling terminal of the process". В переводе на русский это значит так: сколько бы su и sudo ты не делал, терминал продолжает принадлежать пользователю, который залогинился на нём самым первым. То есть если в моём случае я зашёл по ssh пользователем root и оттуда сделал `su - appdev`, то whoami считает что я appdev, geteuid вернёт что надо, в LOGNAME будет написано appdev. И лишь клиент mysql посмотрит кому принадлежит терминал и поймёт, что всё иллюзия, а я на самом деле root:
... readlink("/proc/self/fd/0", "/dev/pts/0", 511) = 10 stat64("/dev/pts/0", {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0 ...А пароль у root в mysql пуст. Бинго, мы вошли.
С перенаправлением же stdin становится не терминалом, а пайпом. Пайп принадлежит тому, кто его создал: appdev. У appdev в mysql пароль не пустой -> ошибка.
Такой день.