Linux get vmware tools version

$( { find /sbin /usr/sbin /usr/local/bin /bin /usr/bin -name 'vmtoolsd'; echo /bin/true; } | head -n1 ) -v

Regardless of deployment method (RHEL6 by inserting the virtual disc, or RHEL7 rpm for open-vm-tools), this should work for you.

Update on 2019-08-20

And from PowerCLI:

get-vm | % { get-view $ } | select Name, @{ Name="ToolsVersion"; Expression={$}},@{ Name="ToolStatus"; Expression={$_.Guest.ToolsVersionStatus}}


  1. Original research
  2. Powercli – How to get Vmware tools version – Virtual Me

Audit sudo docker usage


grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -vE -- "(-u|--user)"
grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -E -- '(-u|--user)\s*root'


One way to secure docker is to allow users to run it with sudo. Alternatively, you can add users to a group named “docker,” but this doesn’t provide the auditing that sudo has by default.

So you can whip up a nice, neat little sudoers.d file similar to:

User_Alias CONT_POC_USERS = %container_sudoers@ADDOMAIN
Runas_Alias CONT_POC_RUNAS = root
Host_Alias CONT_POC_HOSTS = cn-node-5*, cn-node-5*
Cmnd_Alias CONT_POC_CMNDS = /usr/bin/docker *

With a security posture where you will not allow anything to run in a container as root, you can audit compliance with a few regular expressions.

grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -vE -- "(-u|--user)"
grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -E -- '(-u|--user)\s*root'

I haven’t figured out how to have the negative and positive searches in one string, so any input there would be appreciated!

Also, I have not figured out how to actually enforce running the docker exec command only with a -u username flag, without writing a much more complicated whitelist of docker build *, docker commit *, docker container *, docker cp * et al statements which seems like a lot of work but might ultimately be necessary.

Convert input sets of numbers to numerical sequences


I wrote a function for shell (basically bash) that makes it possible to convert a series of numbers such as “1,5-8,15” into a completely enumerated sequence, so 1 5 6 7 8 15.

I needed this to facilitate passing parameters to another function, but with the ability to give arbitrarily-grouped sets of numbers.

You can see my gist on github.

convert_to_seq() {
  printf "${@}" | xargs -n1 -d',' | tr '-' ' ' | awk 'NF == 2 { system("/bin/seq "$1" "$2); } NF != 2 { print $1; }' | xargs

convert_to_seq "$1"

Try it out for yourself! If you are looking for such a function, here you go.


Input: 1,5,8-10
Output: 1 5 8 9 10

Input: 500-510,37
Output: 500 501 502 503 504 505 506 507 508 509 510 37

Cinnamon adds “Show all workspaces” setting to Alt-tab appSwitcher

The story

I recently made a pull request to Cinnamon to add the “Show all workspaces” setting to the window list of the panel. To complement this feature, I decided to add the feature to the alt-tab utility.

My journey began with trying to find the alt-tab code in the Cinnamon project. It took me quite a while, but eventually I found it in appSwitcher.js. At first I started tinkering with lines 36-39

function matchWorkspace(win) {
    return win.get_workspace() == this && !win.is_skip_taskbar();

But this proved to not be the right spot. Later on I realized this was not the correct spot logically, but putting code here would work. It just wouldn’t make sense underneath the title “matchWorkspace.” You shouldn’t even get to the matchWorkspace function if you’re just showing all workspaces anyway.

So then I found this section of code

            // Switch between windows of same application from all workspaces
            let focused = global.display.focus_window ? global.display.focus_window : windows[0];
            windows = windows.filter( matchWmClass, focused.get_wm_class() );
            // Switch between windows of current workspace
            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
            if (!this._showAllWorkspaces) {
                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );

And that was what I wanted. The snippet above already includes my adjustment. Line 73 is the logic that reads the gsettings schema. And it took me a while to get this part to work. At first I had the read-schema code up beside the other global.settings.get_boolean at line 112 in the AppSwitcher.prototype._init: function(binding). But it took me a while to figure out the scoping of the variable was not correct for my needs. Reading the gsetting schema in the prototype did not set the variable for the function at line 73, function getWindowsForBinding(binding).

I also had to learn about the gsettings schema. I’ve dabbled with dconf before. But apparently adding a new key is a little more complicated that just

dconf load /org/cinnamon <<EOF
alttab-switcher-show-all-workspaces true

I learned that for gsettings you have to modify the xml-defined schema. I found it at /usr/share/glib-2.0/schemas/org.cinnamon.gschema.xml. My addition is pretty basic, at lines 541-545.

    <key type="b" name="alttab-switcher-show-all-workspaces">
      <_summary>Show all windows from all workspaces</_summary>

I also found file /usr/share/cinnamon/cinnamon-settings/modules/ and added the widget for this setting.

            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")

So I made my changes and then restarted Cinnamon. Still no go. After a lot of searching, I finally found the important part: I needed to run glib-compile-schemas!

pushd /usr/share/glib-2.0/schemas; glib-compile-schemas .; popd;

Now I finally had success! I submitted pull request #6938 and within a day my changes were approved and merged.

The commit as a patch

diff --git a/data/ b/data/
index 71e09aca..17fe5dc4 100644
--- a/data/
+++ b/data/
@@ -538,6 +538,11 @@
       <_description>Duration of the effect (in milliseconds)</_description>
+    <key type="b" name="alttab-switcher-show-all-workspaces">
+      <default>false</default>
+      <_summary>Show all windows from all workspaces</_summary>
+    </key>
     <key name="bring-windows-to-current-workspace" type="b">
       <summary>Brings windows requiring attention to the current workspace</summary>
diff --git a/files/usr/share/cinnamon/cinnamon-settings/modules/ b/files/usr/share/cinnamon/cinnamon-settings/modules/
index 4875346e..080026ab 100755
--- a/files/usr/share/cinnamon/cinnamon-settings/modules/
+++ b/files/usr/share/cinnamon/cinnamon-settings/modules/
@@ -129,6 +129,9 @@ class Module:
             widget = GSettingsSpinButton(_("Delay before displaying the alt-tab switcher"), "org.cinnamon", "alttab-switcher-delay", units=_("milliseconds"), mini=0, maxi=1000, step=50, page=150)
+            widget = GSettingsSwitch(_("Show windows from all workspaces"), "org.cinnamon", "alttab-switcher-show-all-workspaces")
+            settings.add_row(widget)
 class TitleBarButtonsOrderSelector(SettingsBox):
     def __init__(self):
         self.schema = "org.cinnamon.muffin"
diff --git a/js/ui/appSwitcher/appSwitcher.js b/js/ui/appSwitcher/appSwitcher.js
index f161350c..d36d3bf2 100644
--- a/js/ui/appSwitcher/appSwitcher.js
+++ b/js/ui/appSwitcher/appSwitcher.js
@@ -70,7 +70,10 @@ function getWindowsForBinding(binding) {
             // Switch between windows of current workspace
-            windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            this._showAllWorkspaces = global.settings.get_boolean("alttab-switcher-show-all-workspaces");
+            if (!this._showAllWorkspaces) {
+                windows = windows.filter( matchWorkspace, global.screen.get_active_workspace() );
+            }



  1. Need to use glib-compile-schemas

I am now an open source contributor!


I use open-source software every day, since November 2015. That was the year of Linux on the Desktop for me. I picked as my desktop environment Cinnamon.

I normally don’t use virtual desktops or “workspaces,” but on one laptop I was for a while. It was actually a KDE Plasma 5 installation, which reinforced my plans to stick to Cinnamon as my heavyweight DE. However, the KDE Plasma virtual workspaces worked fine, and provided all sorts of options for the window list and alt-tab switcher for listing windows across all the workspaces. Cinnamon did not have such an offering, so when I finally replaced KDE with Cinnamon on that workstation, I just reverted to my single-workspace workflow.

I told someone online (probably in the #korora channel at that I was willing to pay money for Cinnamon to provide a window list option for displaying the windows from all workspaces. Well, as of October 2, I guess I owe myself $50.

Check out my merged pull request to Cinnamon! I added the feature, as a boolean setting, to the mainline Cinnamon window list applet. So eventually my option will be included in the Fedora Cinnamon build down the line. For the time being, though, I’m going to continue to use my separate applet that provides my feature.

Get Windows license key from your hardware in Linux

If you are running on hardware that originally came with a licensed Microsoft Windows operating system, you should check to see if you can get the license key from your hardware.

sudo hexdump -s 56 -e '"MSDM key: " /29 "%s\n"' /sys/firmware/acpi/tables/MSDM
MSDM key: 12345-09876-ABCDE-FGHIJ-ZYXWV (obscured, of course)

Or another way:

sudo cat /sys/firmware/acpi/tables/MSDM | strings

I never came across this tidbit until today! Apparently it is well-known throughout the Internet.



  1. Found it first at
  2. Strings method

Docker cannot write to mounted volume

So you’ve already investigated the permissions, and the selinux context. There are no errors in the audit logs.

And if you’re using a directory like /var/lib/docker/db, it will have context unconfined_u:object_r:container_var_lib_t:s0.

For mounting with -v /var/lib/docker/db/appname:/opt/application/ and it to be readable, you will need a new context.

semanage fcontext -a -t svirt_sandbox_file_t '/var/lib/docker/db(/.*)?'