ImRaphael
ImRaphael

Reputation: 206

Passing function arguments to multiple commands [fish shell]

I checked the fish documentation, but I did not find what I needed (or if I did, I didn't understand it).

I made a function in fish that suspends my PC after some time:

function ss --d 'sleeps the pc after specified time' 
    sleep $argv && systemctl suspend
end

Then I type ss 20s and it shuts down the PC in 20 seconds.

But what if I want to pass flags to systemctl suspend? Do I also need $argv after that command in the function?

I did try something similar, but I got a Too many arguments error.

Upvotes: 0

Views: 1344

Answers (1)

NotTheDr01ds
NotTheDr01ds

Reputation: 20640

Well first, I think the Too many arguments came from passing any additional argument to systemctl suspend. As far as I know, it doesn't have any additional options, does it? Even if I call sudo systemctl suspend help (or anything as an extra argument), I get the same error.

But as for how to structure a function to handle passing different arguments to multiple commands ...

You are correct on the second point. The documentation covers it, but I absolutely understand that it can be difficult for new users to know what they are looking for. I still find things that are "new to me" when reading the doc again, even after using fish for over a year now.

Hopefully by pointing out the relevant information, it will make more sense. Don't worry, I'll give you the "answer", too, but I want to make sure you have the background you need to understand it.

First, in the Introduction - Functions section, the key takeaway is:

$argv is a list variable

From there, we need to know how to work with list variables. There are two sections that cover that. First Functions - Lists and second, how to access the list variable contents through indexing.

Note that, unlike many languages, fish indices start at 1. So your sleep argument (the first number you pass in, will be $argv[1]. The second, $argv[2], and so on, of course. So if you just want two arguments, that's all you need.

But if you want "all the rest of the arguments" (regardless of how many) to be passed to systemctl suspend, that gets a bit more tricky. That's going to be $argv[2..-1], which means "the second argument through the last argument."

So it should be:

function ss --d 'sleeps the pc after specified time' 
    sleep $argv[1] && systemctl suspend $argv[2..-1]
end

Again, that assumes that you have a valid argument to pass to suspend in the first place, of course.

Upvotes: 3

Related Questions