My use case:
I need to remove all dev packages listed in composer.json file. Suppose I have two packages: projectx/package-nice and projecty/package-good. To remove them I need to run:
$ composer remove --dev projectx/package-nice projecty/package-good
So I build this command to extract the package list:
echo $(composer show -s | grep -E "^[a-z]+/[0-9a-z_-]+" | awk '{print $1}' | xargs)
This return the list of packages, exacly like this: projectx/package-nice projecty/package-good
So I tried to run the command below, but didn't work because bash is interpreting the return as a single string enclosed by quotes:
$ composer remove --dev $(composer show -s | grep -E "^[a-z]+/[0-9a-z_-]+" | awk '{print $1}' | xargs)
It's the same as:
$ composer remove --dev "projectx/package-nice projecty/package-good"
So, what am I doing wrong?
edit 1:
Note that the problem is not about the parsing. The $() is returning the expected values separated by spaces. The issue is about WHY bash is interpreting this return as a unique value.
As @MarcusMüller noted, this problem shouldn't be happening. Inside /etc I ran:
$ ls $(ls | head -n 2)
and the executed command was ls file1 file2 and not ls "file1 file2", so I don't understand why this is happening. Maybe it's because composer is just a script that is run by php, and this is interfering with something?
Thank you.
edit 2:
[SOLVED]
Thanks to @q.undertow insights I managed to find a solution. The problem was being caused by a newline in the return of $(), so I added -d '\n' to xargs and it worked. Here is the full command just for the sake of completeness:
$ composer remove --dev $(composer show -s | grep -E "^[a-z]+/[0-9a-z_-]+" | awk '{print $1}' | xargs -d '\n')