Skip to content
Advertisement

/proc/meminfo not updating when reading from ssh script

I have the following script in bash:

ssh user@1.1.1.1 "echo 'start'
   mkdir -p /home/user/out
   cp /tmp/big_file /home/user/out
   echo 'syncing flash'
   sync
   while [[ $(cat /proc/meminfo | grep Dirty | awk '{print $2}') -ne 0 ]] ; do
      echo "$(cat /proc/meminfo)"
      sleep 1
      sync
   done
   echo 'done'"

I have my host PC and a target PC which I am copying to. Before I run this script I have already scp’d a big file into /tmp on the target.

When I run this script it copies the file /tmp/big ok, but when it enters the loop to sync the flash and I wait for meminfo Dirty to get to zero what I see is always Dirty: 74224 kB repeated in the loop.

However in a different ssh session logged in to the target I have it running:

watch -n1 "cat /proc/meminfo | grep Drity"

And I see this count down from ~74000kb to 0kB.

The difference is that the ssh session doing the watch is logged in as root and the ssh is logged in a user.

So I did the same test with the ssh shell logged in as user and I saw always 0kb in Drity…

Does this imply that the user can’t read meminfo relating to the whole system? – how can I tell when the flash has sync’d as a non-root user?

Advertisement

Answer

Since the argument to ssh is in double quotes, variables and command substitutions are expanded locally on the client before sending the command, they’re not done on the remote machine. Since they’re substituted on the client, you’ll obviously get the same result each time through the loop (because the client isn’t looping).

You should either escape the $ characters so they’re sent to the server, or put the command inside single quotes (but the latter makes it difficult to include single quotes in the command).

ssh user@1.1.1.1 "echo 'start'
   mkdir -p /home/user/out
   cp /tmp/big_file /home/user/out
   echo 'syncing flash'
   sync
   while [[ $(awk '/Dirty/ {print $2}' /proc/meminfo) -ne 0 ]] ; do
      cat /proc/meminfo
      sleep 1
      sync
   done
   echo 'done'"

There’s also no need for cat /proc/meminfo and grep Dirty in the command substitution. awk can do pattern matching and take a filename argument.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement