• Korthrun@lemmy.sdf.org
      link
      fedilink
      arrow-up
      16
      ·
      edit-2
      24 days ago

      This is a command that throws a permission denied error while trying to create a symlink to a file that almost certainly does not exist.

      It’s like someone turning to you and saying “Knick knack!” then waiting for you to ask “who’s there?”

    • jim3692@discuss.online
      link
      fedilink
      arrow-up
      10
      arrow-down
      1
      ·
      edit-2
      24 days ago

      In bash, when you redirect the output of a command to /dev/null, like cat /etc/passwd >/dev/null, you are silencing the output.

      There are cases that this is useful, for example when checking if an application is installed:

      node -v >/dev/null && echo "Node.js is installed"

      This line tries to get the version of Node.js, but it silences the output. That’s because we don’t care about the version. We only care about whether the execution was successful, which implies the existence of Node.js in the system.

      • Korthrun@lemmy.sdf.org
        link
        fedilink
        arrow-up
        10
        arrow-down
        2
        ·
        edit-2
        24 days ago

        Dear linux newbies of the fediverse:

        Please do not run cat for the sole purpose of copying a single files content to STDOUT

        Your system almost certainly has a pager on it (e.g. ‘less’, ‘more’, ‘most’). Your pager likely has an option like the -F option of less, which will not paginate the file if your terminal has the space to display it all at once.

        You do not need to involve cat to get a files contents into a variable. Any POSIX compliant shell will support MYVAR=$(</tmp/myfile)

        You do not need to involve cat to iterate over the lines of a file. You can do things like:

        while read myline
        do
            printf "found '%s'\n" "$myline"
        done </tmp/myfile
        

        If you want to concatenate multiple files, but do not care if they all exist, you might use /dev/null to suppress the “no such file” error from cat as such cat file1 file2 file3 2>/dev/null. Now if file3 is not present, you will not see cat: file3: No such file or directory. 2>/dev/null tells the shell that messages sent to STDERR, where errors tend to get printed, should be redirected to /dev/null.


        Please do not invoke a command only to see if it is available in the directories listed your PATH environment variable

        As an aside this is not the same as seeing if it’s installed.

        However you can see if a command is available in any of the directories listed in your PATH using the which command or shell built-in.

        You might want to do something like:

        #!/bin/bash
        
        which node &> /dev/null
        HAS_NODE="$?"
        
        # ... MORE CODE HERE ...
        
        if [[ $HAS_NODE ]]
        then
            # something you only do if node is present
            :
        else
            # do something else or print a friendly error
            :
        fi
        

        This way you don’t see the output of the “which” command when you run the script, but you do get it’s exit code. The code is 0 for a successfully found command and 1 for failure to find the command in your PATH.

        • qqq@lemmy.world
          link
          fedilink
          arrow-up
          3
          ·
          edit-2
          24 days ago

          Alternatively, use your shell however you want. And which isn’t POSIX so I wouldn’t use that in a shell script you intend to share.

          • Korthrun@lemmy.sdf.org
            link
            fedilink
            arrow-up
            1
            ·
            edit-2
            24 days ago

            Once upon a time I would have been more particular about the “which issue”. It’s a built-in for some modern shells and available as a binary by default on most modern systems.

            You are correct though, if you want to write a 100% POSIX compliant shell script you’re better off using command, type or actually looping over the contents of $PATH and checking for the presence of your desires binary.

            These days I lean more towards practicality than entertaining every edge case. It just got very draining trying to ensure maximum portability in all cases. Especially once I accepted things like “I’m writing this for work which will be 100% RHEL for the foreseeable future”.

            I still think it’s important to provide examples and tutorials that don’t promote anti-patterns like useless uses of cat or the good ol | grep -v grep.

        • Gronk@aussie.zone
          link
          fedilink
          English
          arrow-up
          1
          ·
          24 days ago

          Huh TIL thank you, suppose I should make the leap to learn bash properly instead of clinging onto my perl scripts

            • Gronk@aussie.zone
              link
              fedilink
              English
              arrow-up
              2
              ·
              24 days ago

              I absolutely love perl, I’ve fallen out of professional development but I would take a job to maintain a legacy perl codebase in a heartbeat.