Permission denied on executable in Azure Functions (C#, Linux)

Michał Grzyśka 0 Reputation points
2024-09-26T10:02:40.94+00:00

I am trying to run packed to a single file ffmpeg on Linux on Azure function:

 var ffmpeg = $"/home/site/wwwroot/ffmpeg";
 var videoPath = Path.GetFullPath($"SampleVideo1.mp4");
 var ffmpegCommand = $"{ffmpeg} -i \"{videoPath}\"";

 using Process process = new();
 process.StartInfo.FileName = "bash";
 process.StartInfo.Arguments = $"-c \"{ffmpegCommand}\"";
 process.StartInfo.UseShellExecute = false;
 process.StartInfo.CreateNoWindow = true;
 process.StartInfo.RedirectStandardOutput = true;
 process.StartInfo.RedirectStandardError = true;

 process.Start();
 var output = await process.StandardOutput.ReadToEndAsync();
 var error = await process.StandardError.ReadToEndAsync();

 await process.WaitForExitAsync();

This should be a generic solution to be able to get output from any executable, not only ffmpeg.

Problems I encountered:

  1. Using script/executable directly (without bash) with UseShellExecute = false causes permission denied error, so I set it to true
  2. Using script/executable directly with UseShellExecute = true causes the impossibility of fetching output/error data from process.

What I need is to be able to run a script/executable and be able to get it's output. I found a solution that I can use bash without permission denied, run my aim file with -c parameter, UseShellExecute = false and I will be able to get it's output.

As side solution I am trying to run bash with UseShellExecute = true and trying to save output to a file with -c "commandhere > somefile.txt.

In both cases I get an error:

bash: line 1: /home/site/wwwroot/ffmpeg: Permission denied\n

I tried combinations mentioned before, also I tried:

 var chmodStartInfo = new ProcessStartInfo
 {
     FileName = "chmod",
     Arguments = $"+x {ffmpegPath}",
     RedirectStandardOutput = false,
     RedirectStandardError = false,
     UseShellExecute = true,
     CreateNoWindow = true
 };

 using (var chmodProcess = new Process { StartInfo = chmodStartInfo })
 {
     chmodProcess.Start();
     await chmodProcess.WaitForExitAsync();
 }

before the bash process, but it results with same permission denied problem.

Files are uploaded with "Copy always" options (both sample video and ffmpeg) and they are visible in wwwroot directory.

Azure Functions
Azure Functions
An Azure service that provides an event-driven serverless compute platform.
4,953 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,887 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Bruce (SqlWork.com) 64,816 Reputation points
    2024-09-26T16:05:50.35+00:00

    on linux, UseShellExecute = true, means use the GUI shell to run the command, not the current process. this will not work in azure (as you have found). only when UseShellExecute = false can you can redirect input, output and error.

    it is not clear why you want to use bash. just run the ffmpeg with redirected output, and stream the output to a file.

     var ffmpeg = $"/home/site/wwwroot/ffmpeg";
     var videoPath = Path.GetFullPath($"SampleVideo1.mp4");
     var ffmpegCommand = $"-i \"{videoPath}\"";
     var outPath = "somefile.mp4";
    
     using Process process = new();
     process.StartInfo.FileName = ffmpeg;
     process.StartInfo.Arguments = ffmpegCommand;
     process.StartInfo.UseShellExecute = false;
     process.StartInfo.RedirectStandardOutput = true;
     process.StartInfo.RedirectStandardError = true;
    
     process.Start();
    
     using (var fileOut = new FileStream(outPath, FileMode.Create))
     {
        var outTask = process.StandardOutput.BaseStream.CopyToAsync(fileOut);
        var errTask = process.StandardError.ReadToEndAsync();
        await Task.WhenAll(outTask, errTask, process.WaitForExitAsync());
     }
    

    note: you could pass the output file name to the ffmpeg as a command line parameter instead.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.