0

From the command line, this opens two files in my phpstorm application:

git diff --name-only final-migration | xargs pstorm

When I create an alias in my ~/.bash_profile:

alias ropen="git diff --name-only $1 | xargs pstorm"

and call it from the same directory as the successful command:

ropen final-migration

Nothing happens.. I've tried altering the alias so that it echos instead of xargs pstorm which works as expected. It seems like xargs is where the problem lies when it's being used in an alias.. I'm not sure what I'm missing.

John Hunt
  • 4,265
  • 8
  • 45
  • 59
  • Note: I'm using OSX where things are a little different sometimes. – John Hunt Jul 05 '18 at 09:22
  • The aliases have "search & replace" behaviour. `bash` replaces the `ropen` alias and your command becomes `git diff --name-only | xargs pstorm final-migration`. You have to turn your alias into a function to use arguments. – axiac Jul 05 '18 at 09:25
  • 3
    @JohnHunt: Make it a function as `ropen(){ git diff --name-only "$1" | xargs pstorm ; }` – Inian Jul 05 '18 at 09:27
  • @Inian This behaved in the same way, nothing happened (yes, I re 'source'd my file too..) – John Hunt Jul 05 '18 at 09:31
  • I created two functions to test using a function, the same behaviour as using an alias was observed. I used a test function to make sure I wasn't going mad: The 'test' function was just: function test() { echo "$1" | echo ; } – John Hunt Jul 05 '18 at 09:58
  • Your test function is very strange. `echo text | echo` will print just a newline because `text` is send to a pipe which `echo` never reads. – Socowi Jul 05 '18 at 10:36
  • Shrug, the test worked. – John Hunt Jul 05 '18 at 12:55
  • 1
    Don't name your test functions `test` as it is the name of both a built-in and a binary, which can lead to another `test` than yours being called. – Benjamin W. Jul 05 '18 at 13:32

2 Answers2

1

First Problem

Aliases do not work with parameters like $1. The only way for aliases to use arguments is to put them at the end. But even if $1 would work for aliases, your definition wouldn't work, because "$1" is expanded at the time of definition.
You can print the value of "$1" with echo "$1". For me, its empty. So the alias ...

alias ropen="git diff --name-only $1 | xargs pstorm"

... would be equivalent to ...

alias ropen="git diff --name-only | xargs pstorm"

To use $1 as intended, write a function:

ropen() { git diff --name-only "$1" | xargs pstorm; }

Possible Second Problem

xargs will mangle the arguments if the printed paths contain spaces. Assume git diff --names-only would print the paths a b/c and x/y z, then xargs would construct the command pstorm "a" "b/c" "x/y" "z". None of these files exist.

To allow spaces, use xargs -d '\n' pstorm, this will construct the correct command pstorm "a b/c" "x/y z".

Socowi
  • 25,550
  • 3
  • 32
  • 54
  • Neither of your solutions are working for me, I suspect this is a failing of Apple's implementation of xargs or something like that.. I don't get an error, I just get nothing as per using an alias. – John Hunt Jul 05 '18 at 12:02
  • Another solution I came up with myself was to use the backtick operator, however I still had trouble getting the argument into it: eg `pstorm \`git diff --name-only "$1"\`` – John Hunt Jul 05 '18 at 12:05
  • That would be `ropen() { pstorm $(git diff --name-only "$1"); }` and works only when the printed paths don't contain symbols like space or `*`. Can you give us the output of `ropen ...` with `ropen() { git diff --name-only "$1"; }` and `xargs --version`? – Socowi Jul 05 '18 at 12:09
  • ~ ropentest master db/migrations/20180704142923_create_supplier_terms_table.php packages/netsuite/src/NetsuiteVendorClient.php src/Entity/Supplier/SupplierTermEntity.php ...etc xargs version, it won't tel me: I just get `xargs: illegal option -- -` I did look at the man page, it's BSD 2004 version I think? Hard to format this in a comment, but to sum up your test ropen() function worked as expected. Xargs is some weird BSD version. – John Hunt Jul 05 '18 at 12:52
  • 1
    @JohnHunt You can get the GNU `findutils` that contain GNU xargs. – Benjamin W. Jul 05 '18 at 13:33
0

The issue was with my version of xargs which is supplied with OSX. By using the GNU version, @socowi's suggestion of using a function worked just perfectly.

To install the gnu version of xargs, I did as @Benjamin W said and used homebrew to install findutils. I then added the path as suggested from installing findutils to my ~/.bash_profile.

John Hunt
  • 4,265
  • 8
  • 45
  • 59
  • Glad to hear your problem was resolved. Accept your own answer to mark the question as closed. – Socowi Jul 06 '18 at 11:03