0

I want to execute following command with system() function,

awk -F [][] '/dB/ { print $2 }' <(amixer sget Master) > sound_level

It gives me the desired output when I write in the terminal. But when I call this command with system function in C it gives me error.

My code is:

#include<stdio.h>
#include <stdlib.h>

int main()
{
        system("awk -F [][] '/dB/ { print $2 }' <(amixer sget Master) > sound_level");
        return 0;
}

It gives me the following error:

sh: 1: Syntax error: "(" unexpected

I have also tried:

awk -F [][] '/dB/ { print $2 }' < /(amixer sget Master /) > sound_level

but it does not work.

Any help is appreciated.

abligh
  • 24,573
  • 4
  • 47
  • 84
space earth
  • 407
  • 4
  • 18

1 Answers1

8

Read system(3). That C function (which you probably should avoid, prefer explicit syscalls(2) like fork & execve) is running the POSIX /bin/sh -c ; read also popen(3).

But your interactive shell is probably bash which behaves differently than POSIX sh, notably for redirections like <(amixer sget Master)

To make things more complex, the /bin/bash program, when invoked as sh, changes it behavior to POSIX sh, so on many systems, /bin/sh is a symlink to /bin/bash ...

So read also the documentation of GNU bash, and Advanced Linux Programming, and Advanced Bash Scripting Guide ...

Then, either set up your pipelines and redirections with explicit syscalls(2), or code some bash or zsh script (but probably not a POSIX /bin/sh one!) to do the work.

I don't know what amixer sget Master does, but perhaps you might consider a pipeline like

 amixer sget Master | awk -F '[][]' '/dB/ { print $2 }'

(and the above pipeline is POSIX sh compatible, so callable from popen(3)...)

I am surprised you need to do all that. I guess that the sound volume could be queried by some pseudo file from /sys/

Learn more about ALSA and read some Guide thru the Linux sound API

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    Don't do that. Either code some `bash` or `zsh` (but not `sh` !!!) shell script and run it from `system`, or use explicit [syscalls(2)](http://man7.org/linux/man-pages/man2/syscalls.2.html) – Basile Starynkevitch Nov 30 '15 at 06:39
  • 1
    Also worth knowing that you can start a shell with [`popen`](http://man7.org/linux/man-pages/man3/popen.3.html) and feed it a script to its standard input from within your C program. That way, you don't need an extra file (that might not be available). Of course, you should only do that for very tiny scripts. – 5gon12eder Nov 30 '15 at 06:46