Search code examples
linuxbashenvironment-variablesnetwork-programming

environment variables not working as network interface name for ip link add


I am attempting to create a network interface using "ip link add". Specifically a veth interface; however, this problem occurs no matter the interface type.

Ex: sudo VAR=somename ip link add $VAR type dummy

results in an interface named "dummy1" instead of "somename". This is the same behaviour as if there was no name specified to begin with.

Ex: sudo VAR=somename ip link add name $VAR type dummy

results in the error 'both "name" and "dev" cannot be used when creating devices.' which makes sense if the $VAR is either being completely ignored or is being treated as an empty string.

Ex: sudo VAR=somename ip link add also_$VAR type dummy

results in an interface named "also_". Which is consistent with the other two examples, but still doesn't really help me figure out why I can't get "ip link add" to recognize an environment variable.

Encapsulating the $VAR in curly braces such as ${VAR} doesn't help. Setting up my variable as a global variable doesn't help. Executing this from a script file rather than the command line doesn't change anything. I cannot for the life of me find anything like this problem on the internet. The MAN pages for ip and ip-link don't appear to make any reference to variables or the $, let alone mention any problems with them. I can't find any restrictions to ifnames that would suggest I cannot use variables with them.

Is it possible to use a bash environment variable as part of (or the entirety of) the name of a network interface being set up via the "ip link add" command?

Thank you.


Solution

  • This ...

    Ex: sudo VAR=somename ip link add $VAR type dummy
    

    ... sets variable VAR in the environment of the ip command, but the $VAR in it is expanded by the shell, prior to executing sudo, much less ip. VAR has not been set in the shell (by that command). So,

    This is the same behaviour as if there was no name specified to begin with.

    Yes, exactly. And sudo runs the given command directly, not via a shell, so quoting the $VAR is not a sufficient solution, even if you tell sudo to pass VAR through, which by default it would not do.

    It's not clear why you want this. Surely avoiding VAR altogether:

    ip link add somename type dummy
    

    would be simpler than what you're attempting. On the other hand, if VAR were defined in the shell from which you launch sudo then you would not be having this issue:

    VAR=somename
    
    # ...
    
    sudo ip link add "$VAR" type dummy
    

    because, again, the $VAR in that command is expanded by the shell.

    (Note that the double quotes are not essential in a context where VAR is defined with a non-empty value consisting only of alphanumeric characters. They are there in case VAR's value does not meet those requirements.)

    I acknowledge your claim that ...

    Setting up my variable as a global variable doesn't help.

    ... but if you're denying that what I just described is effective then I do not believe you. It may be, however, that what you mean by making the variable "global" produces a situation with some significant semantic difference from that.

    Is it possible to use a bash environment variable as part of (or the entirety of) the name of a network interface being set up via the "ip link add" command?

    Yes and no. Unquoted and double-quoted environment variable references appearing on a shell command line are evaluated by the shell, prior to launching the command, not by the command itself. So yes, you absolutely can use environment variable references in shell commands that execute ip, including to convey the interface name. But from the perspective of ip itself, no, it just sees its arguments as opaque strings. It gets whatever the variable reference expanded to, if anything, not the literal text of the variable reference. As such, setting variables in ip's environment would be useful only for variables that ip uses explicitly, if there were any.