8

Is it possible to unset the $1 variable? If not, I can't find out where it is explained in man.

[root@centos2 ~]# set bon jour
[root@centos2 ~]# echo $1$2
bonjour
[root@centos2 ~]# unset $1
[root@centos2 ~]# echo $1$2
bonjour
[root@centos2 ~]#

EDIT:

Finaly, here is what I found out in man (man set option double-dash) to empty all the positional parameters (and the man used the word "unset"!):

If no arguments follow this option, then the positional parameters are unset.

[root@centos2 ~]# echo $1

[root@centos2 ~]# set bon jour
[root@centos2 ~]# echo $1$2
bonjour
[root@centos2 ~]# set --
[root@centos2 ~]# echo $1$2

[root@centos2 ~]#

It's @Jeff Schaller's answer that helped me understand that.

2
  • 4
    I'm not sure what you're asking but you could use 'shift' to make $2 take the place of $1, therefore removing $1. EDIT: Kusalananda has a more expansive answer below.
    – bitofagoob
    May 17 '17 at 20:45
  • You are right my question is not well formed. I was looking for how to empty a positional variable if I had set it.
    – Pozinux
    May 17 '17 at 21:25
21

You can't unset a positional parameter, but you may shift $2 into $1, effectively removing the old value of $2.

$ set -- bon jour
$ echo "$1$2"
bonjour

$ shift
$ echo "$1$2"  # $2 is now empty (i.e. "unset" or "not set")
jour

The shift command will shift all positional parameters one step lower. Command-line parsing loops (that does not use getopt/getopts) commonly shift the positional parameters over each iteration while repeatedly examining the value of $1. It is uncommon to want to unset a positional parameter.

By the way, unset takes a variable name, not its value, so unset $1 will, in effect, unset the variable bon (had it been previously set).

6
  • What about if I want to empty $1? Also, good point on the fact that it would be unset bon. I didn't think about that.
    – Pozinux
    May 17 '17 at 21:30
  • @Pozinux That would be quite an unusual thing to want to do. What is the issue you're trying to solve?
    – Kusalananda
    May 17 '17 at 21:33
  • In fact, I'm learning. I'was trying to understand how setworks. I tried this example with "bonjour" but couldn't find a way how to empty this variable. I mixed a bit with unset. Probably because I did't get yet all the concept about set, unset, env, export etc.
    – Pozinux
    May 17 '17 at 21:36
  • 1
    @Pozinux Well, setting them again would overwrite them, like Jeff shows in his answer.
    – Kusalananda
    May 17 '17 at 21:39
  • When you use getopt or getopts you do use shift. May 18 '17 at 20:55
16

You could empty it, by re-setting the parameters to: "the empty string" followed by "the parameters, starting from the 2nd one":

$ set -- 1 2 3 4
$ printf -- "->%s<-\n" "$@"
->1<-
->2<-
->3<-
->4<-
$ set -- "" "${@:2}"
$ printf -- "->%s<-\n" "$@"
-><-
->2<-
->3<-
->4<-
1
  • Your anwser is nice and right aswell but it took me more time to understand it because of my little shell level... In fact, it helped me to find out about the "--" option that I didn't know (see my edit on my question). Thanks.
    – Pozinux
    May 18 '17 at 17:05
6

Besides all the correct technical answers you should notice that there is a logical flaw in your question. $1, $2,... are not the values of named variables like $A, $B, ..., but the 1st, 2nd,... value of a list of values. Maybe the first value of a list is an empty string but it does not make sense to say my list has no first value. If a list has no first value then it has no value at all and so it is an empty list.

So you cannot "unset" the first value of a list. You can only remove the first value from a list. Then the former 2nd value of the list is now the 1st value of the list, the former 3rd is now the 2nd and so on. This is exactly what the shift operator does.

3
  • Though note that actual arrays don't need to be indexed consecutively from zero, you could go unset A; A[4]=foo; A[7]=bar; and leave with A[0] among others unset (not just empty). And then unset A[4]. But I'm digressing, this doesn't apply to the positional parameters.
    – ilkkachu
    May 18 '17 at 11:26
  • @miracle173, you are right it doesn't make sense. I thought that unset was also used to empty a variable.
    – Pozinux
    May 18 '17 at 11:49
  • @ilkkachu A is an array and not a list of values. A[0], A[1], ... are similar to variables and therefore can be empty
    – miracle173
    May 18 '17 at 12:48
4

No, at least not directly. This syntax should work but yields an error:

$ set bon jour
$ echo $1 $2
$ unset 1
1: not a valid identifier

unset $variable is usually a mistake and unset variable was what was intended. Unfortunately it doesn't work here.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.