1

I'm trying to execute Sox from a Lua script.

It works fine when I pass literals as arguments.

os.execute('"C:\\Sox\\sox.exe" -S C:\\SoX\\test.wav -r 22050 C:\\Sox\\SoX_out.wav')

or

os.execute [["C:\\Sox\\sox.exe" -S C:\\SoX\\test.wav -r 22050 C:\\Sox\\SoX_out.wav]]

however, what I'd like to do (as example), when I try this:

filename = "C:\\SoX\\test.wav"
os.execute('"C:\\Sox\\sox.exe" -S filename -r 22050 C:\\Sox\\SoX_out.wav')

I get:

C:\Sox\sox.exe FAIL formats: can't open input file `filename': No such file or directory

So my question is how to pass a string properly as command argument ?

1
  • 2
    If your file names can contain spaces, more quotes are required: os.execute([[""C:\Sox\sox.exe" -S "]]..filename..[[" -r 22050 "]]..filename2..[[""]]) Commented Apr 26, 2017 at 20:01

1 Answer 1

4

In Lua, a string literal is exactly and only that string. Strings don't know anything about variables, the global environment, local variables, etc. They're just strings. The string "filename" in Lua will always be a string of 8 characters. It will not go out and try to find a variable named filename and extract something from it.

What you want is to build a string, from multiple strings. Part of the string will come from literals, and part will come from a variable. Lua has several tools for that. The simplest is the .. concatenation operator:

[["C:\Sox\sox.exe" -S ]] .. filename .. [[ -r 22050 C:\Sox\SoX_out.wav]]

This builds a new string from a string literal, the contents of the filename variable, and another string literal. The spaces you see at the end of the first literal and the beginning of the second are necessary, since Lua will not insert spaces between the two concatenated pieces.

For more complex cases, it's useful to just build a table of parameters and use table.concat to build a string out of them:

local params =
{
  [[C:\Sox\sox.exe]],
  "-S",
  filename,
  "-r 22050",
  [[C:\Sox\SoX_out.wav]]
}

os.execute(table.concat(params, " "))

Note the lack of spaces in the string literals. This is because table.concat's second parameter is a string to be inserted between the entries in the array. So between each array element will be a space; we don't need to manually add them.

Sign up to request clarification or add additional context in comments.

2 Comments

Using a table is a nice solution I was unaware of, thanks. But your first suggestion doesn't work for me. When I do os.execute[["C:\Sox\sox.exe" -S ]] .. filename .. [[ -r 22050 C:\Sox\SoX_out.wav]] I get "unexpected symbol near '..' Why ? This version works fine though: os.execute('"C:\\Sox\\sox.exe" -S ' .. filename .. ' -r 22050 C:\\Sox\\SoX_out.wav')
@nofish: It doesn't work because you didn't put parenthesis around the argument to os.execute in the first one. You did in the version that works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.