How Elixir System cmd or shell works?

I want to run backup of postgresql database with Elixir. How can I do it with elixir script ?

defmodule PmLogin.DatabaseBackup do
  require Logger

  def start do

  def start_backup do"Change directory to postgres path")
    System.cmd("cd", ["/"])

    System.cmd("cd", ["C:\\Program Files\\PostgreSQL\\14\\bin"])"Set postgres password")
    System.cmd("set", ["PGPASSWORD=postgres"])"Execute database backup")
    System.cmd("pg_dump", ["-h 'localhost' -U 'postgres' -f 'C:\\Users\\web\\Videos\\backup.sql' 'pm_users'"])

    Logger.alert("Backup successfully")

** (ErlangError) Erlang error: :enoent
(elixir 1.13.0) lib/system.ex:1044: System.cmd(“cd”, [“/”], [])
(pm_login 0.1.0) lib/pm_login/database_backup.ex:10: PmLogin.DatabaseBackup.start_backup/0

System.cmd doesn’t control a shell. It does start executables directly. There’s also no shared state between multiple System.cmd calls. I’d suggest putting things in a shell script and run everything with a single System.cmd call.

1 Like

Ok… but how do I change this code?

Give the cd and env options to System.cmd directly on the call using pg_dump

1 Like

Ok, thank you let’s try

I can see you are on windows.
I recommend you run your external program on a windows cmd shell and when you have the right cmd line you run it through cmd.exe like in my example below.

  def add_banner_to_video(record_path, match_id) do"FFmpeg add_banner_to_video start...")

    output_path = "#{@records_final}#{match_id}.mp4"

    args =
        # cmd.exe need this option
        "-i #{record_path}",
        "-i #{@banner}",
        "-vcodec libx264 -crf 17 -preset ultrafast",
        "-c:a copy",
      |> Enum.join(" ")

    {_, 0} = System.cmd("cmd.exe", [args], stderr_to_stdout: true)"FFmpeg add_banner_to_video end")


I fixed it by running command with Thanks all !!!

   # Execute commands in shell to backup postgresql database"🔧 Backup starting ")"PGPASSWORD=postgres pg_dump -U postgres -d pm_users -f '#{db_name}'")

      # Say that backup is finished"📦 Backup finished at 👉 #{datetime_to_finished}")

Beware that if someone will be able to control db_name then they can capture whole machine.