Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QProcess on MacOS has some issues
Forum Updated to NodeBB v4.3 + New Features

QProcess on MacOS has some issues

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 1.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • vivianV Offline
    vivianV Offline
    vivian
    wrote on last edited by vivian
    #1

    Qt 5.12

    I am trying to get the volume ID on macOS and using the following function:

    QString getVolumeInfo()
    {
        QString volumeID = "Cannot find the volumeID";
        QProcess p;
        //diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)
        QString command = "diskutil";
        QStringList args;
        args << "info" <<  "$(df -h / | tail -1 | cut -d' ' -f 1)";
        p.start(command, args);
        p.waitForStarted();
        p.waitForFinished();
        foreach(QString line, QString(p.readAll()).split("\n"))
        {
           if(line.contains("Volume UUID:"))
               volumeID = line;
        }
        return volumeID;
    }
    

    I have to use the diskutil because of the limitation with macOS. However, QProcess, reading the object has nothing in it.

    Command on terminal: diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)
    which returns a ton of information like:
    ...
    SMART Status: Verified
    Volume UUID: 954BACF1-EBC5-4D14-86FB-0912CF7F839C
    Disk / Partition UUID: 954BACF1-EBC5-4D14-86FB-0912CF7F839C

    Disk Size: 500.1 GB (500068036608 Bytes) (exactly 976695384 512-Byte-Units)

    ....

    When I try to add qDebug() to debug I get the following: true - "Could not find disk: $(df -h / | tail -1 | cut -d' ' -f 1)\n"

    So seem like the arguments is not formatted or something?

    I am trying to implement: https://apple.stackexchange.com/questions/50302/how-can-i-tell-which-volume-the-operating-system-is-on

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      To do such chaining you should use QProcess::setStandardOutputProcess and create as many QProcess as command you have.

      However, you can avoid using cut and simply use QString parsing on the output of tail -1 or may just par the output of df in your application and then call diskutil on the result.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • W Offline
        W Offline
        wrosecrans
        wrote on last edited by
        #3

        You will need to explicitly run a shell if you want to have the $() be evaluated by a shell. When you run a command like that on the command line, the shell spawns four separate processes. One process for df, one process for tail, one process for cut. And the finally when the result of the $() is fully evaluated, it runs a process for diskutil, with the result of the $() block. The shell doesn't try to pass the whole raw command line to exec to try and have the kernel sort it out -- it has to do that itself. If you don't want to handle it yourself, you need to run something like sh -c 'diskutil info $(foo)'

        JonBJ 1 Reply Last reply
        2
        • W wrosecrans

          You will need to explicitly run a shell if you want to have the $() be evaluated by a shell. When you run a command like that on the command line, the shell spawns four separate processes. One process for df, one process for tail, one process for cut. And the finally when the result of the $() is fully evaluated, it runs a process for diskutil, with the result of the $() block. The shell doesn't try to pass the whole raw command line to exec to try and have the kernel sort it out -- it has to do that itself. If you don't want to handle it yourself, you need to run something like sh -c 'diskutil info $(foo)'

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @wrosecrans

          you need to run something like sh -c 'diskutil info $(foo)'

          That's how I would do if I were the OP and I didn't want to start creating separate processes for each segment (though as @SGaist observed you could probably do this one yourself by skipping tail & cut and parsing yourself).

          However, though I haven't tested, I would have thought that sh, Bourne shell, was not up to the job of $(...) and you'd want something more like /bin/bash -c?

          W 1 Reply Last reply
          0
          • vivianV Offline
            vivianV Offline
            vivian
            wrote on last edited by
            #5

            Thank you all. I have managed to sort it out after understanding from the comments above. Thank you all.

            I still have to try and cull a few commands off the args but currently, it works and I quite understand the whole situation.

            QStringList args;
            args << "-c" << "diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)";
            p.start("/bin/bash", args);
            
            1 Reply Last reply
            2
            • JonBJ JonB

              @wrosecrans

              you need to run something like sh -c 'diskutil info $(foo)'

              That's how I would do if I were the OP and I didn't want to start creating separate processes for each segment (though as @SGaist observed you could probably do this one yourself by skipping tail & cut and parsing yourself).

              However, though I haven't tested, I would have thought that sh, Bourne shell, was not up to the job of $(...) and you'd want something more like /bin/bash -c?

              W Offline
              W Offline
              wrosecrans
              wrote on last edited by
              #6

              @JonB Yeah, you should probably be explicit about which shell you want. On OS-X 'sh' is apparently bash anyway so it lets me get away with it. It's definitely not a portable assumption though, and could lead to a lot of "It works on my machine" kind of problems.

              /shrug

              wills-mbp:list $uname -a
              Darwin wills-mbp 18.2.0 Darwin Kernel Version 18.2.0: Mon Nov 12 20:24:46 PST 2018; root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64
              wills-mbp:list $sh -c 'echo $(echo 123)'
              123
              wills-mbp:list $sh --version
              GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
              Copyright (C) 2007 Free Software Foundation, Inc.
              
              JonBJ 1 Reply Last reply
              1
              • W wrosecrans

                @JonB Yeah, you should probably be explicit about which shell you want. On OS-X 'sh' is apparently bash anyway so it lets me get away with it. It's definitely not a portable assumption though, and could lead to a lot of "It works on my machine" kind of problems.

                /shrug

                wills-mbp:list $uname -a
                Darwin wills-mbp 18.2.0 Darwin Kernel Version 18.2.0: Mon Nov 12 20:24:46 PST 2018; root:xnu-4903.231.4~2/RELEASE_X86_64 x86_64
                wills-mbp:list $sh -c 'echo $(echo 123)'
                123
                wills-mbp:list $sh --version
                GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
                Copyright (C) 2007 Free Software Foundation, Inc.
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @wrosecrans
                Wow, I wouldn't have known that (only ever having used a Mac just after they were invented)! Under my Ubuntu:

                jon@ubuntu:~$ sh --version
                sh: 0: Illegal option --
                jon@ubuntu:~$ 
                

                That's more to my liking :) Having said that, it appears sh -c 'echo $(echo 123)' does work, though I'm sure it didn't in the 80s! Personally, I'd still rather use backticks...

                Incidentally, in your command prompt I note you have no space after the $. I thought you were typing $sh etc. Don't you/Mac want one? :)

                W 1 Reply Last reply
                0
                • JonBJ JonB

                  @wrosecrans
                  Wow, I wouldn't have known that (only ever having used a Mac just after they were invented)! Under my Ubuntu:

                  jon@ubuntu:~$ sh --version
                  sh: 0: Illegal option --
                  jon@ubuntu:~$ 
                  

                  That's more to my liking :) Having said that, it appears sh -c 'echo $(echo 123)' does work, though I'm sure it didn't in the 80s! Personally, I'd still rather use backticks...

                  Incidentally, in your command prompt I note you have no space after the $. I thought you were typing $sh etc. Don't you/Mac want one? :)

                  W Offline
                  W Offline
                  wrosecrans
                  wrote on last edited by wrosecrans
                  #8

                  @JonB If you wanna really annoy your brain with trivia about bash/sh on OS-X, they are both bash, but they are separate copies of slightly different bash binaries that were built separately, rather than a symlink from one to the other or something:

                  $ ls -lh /bin/bash /bin/sh
                  -r-xr-xr-x  1 root  wheel   604K Nov 29 21:55 /bin/bash
                  -r-xr-xr-x  1 root  wheel   604K Nov 29 21:55 /bin/sh
                  $ md5 /bin/bash /bin/sh
                  MD5 (/bin/bash) = b513c6e7c86e43eb93f4fd56e28bd540
                  MD5 (/bin/sh) = be55e8952a262d0e524239dbf82191ed
                  

                  I have no idea why, but presumably it is possible to get some sort of different behavior between the two shells as a result of them being almost, but not quite, the same thing.

                  I never really noticed my lack of space, but I can see how it would be confusing out of context, ha ha. I have been fiddling with my PS1 prompt recently, so I probably screwed it up then. I now have the output of pwd going the the whizzy (and otherwise mostly useless) touchbar on my MacBook Pro as a part of generating the prompt, so the prompt in the terminal can be quite terse and not take up much space.

                  1 Reply Last reply
                  3

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved