简体   繁体   中英

How do I add some characters at the end of an Ubuntu terminal variable via `awk` or `sed`?

Context

I am currently trying to setup Windows Subsystem 2 for Linux in my Windows 10 Pro OS. After downloading Ubuntu 20.04 LTS from the Microsoft store, installing it, and creating my user profile, I started wondering how I could run and use all the Ubuntu programs that have a graphical interface. I then discovered Xming , which allowed me to establish a connection between my Windows OS and the Ubuntu kernel via IP: everything works fine, except for the fact that since there is no way to set a static IP for the WSL virtual ethernet card, every time I restart my PC I have to check and change the address to which I want to connect. I am currently doing this by editing each time my .bashrc file, and adding a line like

export DISPLAY=172.29.112.1:0.0

which corresponds to the IP I have listed in the IPv4 sub-section of the WSL web configuration. I obtained it by running

ipconfig

inside a PowerShell/Windows terminal. The two zeroes I added to the IP are the ports requested by Xming , (and also, indirectly, the cause of my problem).

My idea has been to try and automate all this process, so that every time I boot my PC I just have to launch Xming and Ubuntu.

Issue description

The problem is that I had close to zero knowledge about terminal syntax, so I managed to come up with just a partial solution: I managed to automatically load the correct IP, but I cannot append the ports without deleting part of the IP itself. This is what I came up with so far:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | grep IPv4 | cut -d: -f2 | awk '{print $1}' | awk 'END{print}')

This line, added to my .bashrc , allows me to get the correct IPv4, which happens to always be the one at the end of the list (hence the second awk call). It invokes the same ipconfig one uses inside Windows, so that I can obtain the desired address. I studied a bit how this syntax works and found some interesting solutions to the next problem, ie attaching the ':0.0' at the end of the query above. One, for instance, is this . Unfortunately, even if replicating that solution works fine with normal strings, it seems like my IP address is stored as a different kind of variable, or at least it behaves differently: trying to apply that same concept makes so that the initial portion of my IP gets overwritten.

What I want

A (possibly) one-line formula like the one I made, but which also incorporates the ports at the end, without overwriting any of the IP's digits. In any case, the DISPLAY variable assigned in the .bashrc must be of the same type of the current one I have with my partial implementation, as I need it to be read by Xming , or any other program. I would also appreciate some explanations about the solution and about the reason of the overwriting phenomenon I described.

What I have tried so far

I have devoted all the afternoon to this issue, starting from learning a little bit of the syntax of the Ubuntu terminal, as well as trying to find examples of sed and awk , among other functions.I also tried many slightly altered versions of my query in order to fit in the ports, but all these tries only yielded syntax errors or the same overwriting effect described above.

Why I am asking this

Given that I expect this to take me probably a little while to solve, and that I am confident this should not be time-consuming at all for anybody with some experience in the field, I hope to receive some help.

Thank you!

Update

After several tries, it turns out that the WSL IP sub-category could indeed be listed in a different position than last. I thought the entries would follow the alphabetical order, but it is clear now that that was just a coincidence.
Thus, if I have something like this: WSL IP 小节

I now have the need to actually grep this precise portion of the ipconfig output, rather than blindly picking the last of the list as I have been doing until now. I have tried to wrap my head around your solutions, and with some further research I managed to find a way to make it work regardless of the postioning:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | awk '/WSL/{getline; getline; getline; getline; print}' | grep IPv4 | cut -d: -f2 | tail -n1 | sed 's/\r//g' | awk 'END {print($1":0.0");}')

obtained attaching @Zilog80 formula. What I understood is that getline should read and ignore the current line and move to the next one, so by doing that 4 times I could apply the rest of the formula to the line I was originally interested in. There are surely better ways to do it, but I can confirm that this is pretty reliable, even if not elegant. Looking forward to see your suggestion/improvements also for this update.

ps I removed part of the IPv6 as I am not aware if that is sensible information; sorry if that was not the case.

The issue you have come from the fact that you're are launching ipconfig.exe, a windows tools for ip adapters, which output with Windows line terminators (CR+LF). That drives AWK to keep the CR in the output, thus overwriting .

To prevent that, filter the damn CR with the sed utility, which permits to remove the troubling CR (\r):

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | grep IPv4 | cut -d: -f2 | tail -n1 | sed 's/\r//g' | awk 'END {print($1":0.0");}')

As @Ed Morton suggested, it may be useful to let know that all your command can be done with AWK only:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | awk -F\: '/IPv4/{adr=$NF}END{sub(/\r$/,"",adr); print adr":0:0"}')

Here's a shorter one-liner leveraging @Zilog80's point about the carriage return:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe| awk '/IPv4/ {addr=$NF} END {printf "%.*s:0.0", length(addr)-1, addr}')

This searches for the lines that have "IPv4" embedded in them and captures the last whitespace-delimited item on the line. At the end, it prints it out, restricting the string to the first length-1 characters (which deletes the carriage return).

Sorry, I haven't read all parts, only your issue description and "what I want". This should help you:

export DISPLAY=$(/mnt/c/Windows/System32/ipconfig.exe | sed 's/\r$//' | awk '/IPv4/{ip=$NF}END{print ip ":0:0"}')
  • Your windows command gives DOS line endings. I convert them with sed .
  • awk stores the last field of all lines containing IPv4 in the variable ip which gets printed in the end.
  • awk can concatenate strings: print ip ":0:0"

PS: Don't forget to replace the previously appended line in your .bashrc .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM