从主机Bash执行rails命令

大家好,

我想从主机 Bash 执行自动化的用户清理任务。手动操作时,我运行:

/var/discourse/launcher enter app
rails c
UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false) 

我有一个包含大量用户名的文本文件,需要从中移除这些用户。手动执行此操作是不现实的。我尝试将删除命令封装在一个 Bash 脚本中。但在执行 launcher app 子命令的 rails c 时,Redis 连接失败:

/var/discourse/launcher run app "echo \"User.find_by_username_or_email('user@example.com')\" | rails c"
Failed to report error: Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) 2 Error connecting to Redis on localhost:6379 (Errno::EADDRNOTAVAIL) subscribe failed, reconnecting in 1 second.

然而,当我使用 export 比较 launcher enter applauncher run app 的环境变量时,它们看起来几乎完全相同。我遗漏了什么?launcher run/ 目录启动,而 launcher enter 直接进入 /var/www/discourse。在执行 rails 之前使用 cd 也无济于事。

有什么建议吗?谢谢!

我认为 docker run 会启动一个新容器。

对于这类情况,我使用 docker exec 而不是 launcher,因为后者会执行许多你并不需要的操作。

1 个赞

谢谢回复。我发现 Rails 在使用 docker exec 时的行为也很奇怪。手动执行时一切正常:

docker exec -it de7f5f6f649c '/bin/bash'
root@discourse-app:/# rails c
[1] pry(main)> User.find_by_username_or_email('myname')

但当我尝试从容器外部执行 rails c 时,却遇到以下问题:

docker exec -it de7f5f6f649c "/usr/local/bin/rails console"
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/usr/local/bin/rails console": stat /usr/local/bin/rails console: no such file or directory: unknown

更有趣的是:

docker exec -it de7f5f6f649c '/bin/bash -c "/usr/local/bin/rails"'
OCI runtime exec failed: exec failed: container_linux.go:367: starting container process caused: exec: "/bin/bash -c \"/usr/local/bin/rails\"": stat /bin/bash -c "/usr/local/bin/rails": no such file or directory: unknown

为什么会有这种差异?

这是预期的行为:你正在指示 Docker 在容器中执行二进制文件 /usr/local/bin/rails console。也就是说,这是一个包含嵌入空格的文件。该文件并不存在。

考虑以下示例:

○ → docker run -i debian /bin/echo hello
hello

○ → docker run -i debian '/bin/echo hello'
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: "/bin/echo hello": stat /bin/echo hello: no such file or directory: unknown.
ERRO[0000] error waiting for container: context canceled 

请按照在容器内执行命令的方式对命令进行引用:

○ → docker exec -i app rails runner 'puts "hello"'
hello

使用 OP 中的示例,以下命令应能正常工作:

docker exec -i app rails runner 'UserDestroyer.new(Discourse.system_user).destroy(User.find_by_username_or_email("user@example.com"), delete_posts: false)'
2 个赞

好吧,这出乎我的意料,因为我没有先阅读手册。感谢你们的快速帮助。

1 个赞