0

I have command, which output two columns. For example:

undefine@uml:~$ uptime -s
2015-10-26 08:47:12

How can i put this two columns into separate variables? I would like to do something like:

undefine@uml:~$ uptime -s | read day hour
undefine@uml:~$ echo $day
undefine@aml:~$

I know, that in bash i can execute it like:

undefine@uml:~$ read day hour <<< $(uptime -s)
undefine@uml:~$ echo $day
2015-10-26

I can also redirect output from uptime to file, and then read from that file:

undefine@uml:~$ uptime -s > tmpfile
undefine@uml:~$ read day hour < tmpfile
undefine@uml:~$ echo $day
2015-10-26

But how to do it "posix sh way", and without creating any temporary files?

Anders
  • 8,307
  • 9
  • 56
  • 88
undefine
  • 142
  • 1
  • 15

3 Answers3

2

If you don't care about the two assigned variables being named $1 and $2, you could use:

set $(uptime -s)

(This is not a completely serious answer.)

sjnarv
  • 2,334
  • 16
  • 13
  • This is good; it overwrites the current positional parameters, but it's usually obvious when the current values need to be preserved and easy to actually do so. – chepner Oct 29 '15 at 14:37
1

In POSIX shell, you can a here document along with command substitution:

read day hour <<EOF
$(uptime -s)
EOF

(Technically, this may still use a temporary file, but the shell manages it for you.)

chepner
  • 497,756
  • 71
  • 530
  • 681
  • What is your problem with your own second example? – Rambo Ramon Oct 29 '15 at 13:41
  • If it has to be one line, use the temporary file and join the commands with `;`: `uptime -s > tmpfile; read day hour < tmpfile; rm tmpfile`. POSIX doesn't provide a one-line method of defining here documents; that's why `bash` and other shells provide here strings. – chepner Oct 29 '15 at 13:41
  • @RamboRamon `<<<` isn't part of the POSIX standard. – chepner Oct 29 '15 at 13:42
  • Which uptime actually takes arguments anyway? I've never seen it before so pretty sure most posix systems will not have it by default as well. – 123 Oct 29 '15 at 13:55
  • @123 That's not really relevant to the question or this answer, which provides a POSIX-compliant way of piping output from one command to a `read` command executed in the current shell. (`uptime` itself is not covered by the POSIX specification, so there's no telling what any particular implementation will accept.) – chepner Oct 29 '15 at 14:07
  • @chepner It's atleast vaguely relevant, as i would assume they want it posixly so that it is portable, but okay. – 123 Oct 29 '15 at 14:10
  • uptime was only simple example ;) – undefine Oct 29 '15 at 14:27
-1

You could split it by piping to cut like so

myVar1=$(echo uptime -s | cut -d" " -f1)
myVar2=$(echo uptime -s | cut -d" " -f2)

This normally works for bash. On sh you would have to use back ticks so

myVar1=`uptime -s | cut -d" " -f1`
myVar2=`uptime -s | cut -d" " -f2`

Hope this helps