74

I am writing a bash script to deal with some installations in an automated way... I have the possibility of getting one such program in 32 or 64 bit binary... is it possible to detect the machine architecture from bash so I can select the correct binary?

This will be for Ubuntu machines.

Mike Stone
  • 44,224
  • 30
  • 113
  • 140
  • Detect what? CPU? OS? Userland availability of a cpu architecture? `/proc/cpuinfo` returning 64-bit when the OS is 32-bit is not very helpful in most cases. – jww Mar 29 '17 at 10:20

8 Answers8

84
MACHINE_TYPE=`uname -m`
if [ ${MACHINE_TYPE} == 'x86_64' ]; then
  # 64-bit stuff here
else
  # 32-bit stuff here
fi
Mike Stone
  • 44,224
  • 30
  • 113
  • 140
bmdhacks
  • 15,841
  • 8
  • 34
  • 55
  • 13
    instead of `${MACHINE_TYPE}` you could just write `$(uname -m)`, and skip the declaration of another variable. – Qsiris Oct 25 '12 at 20:32
  • 7
    Unless you have to use it more then once in your script ... – Abai Jan 29 '13 at 13:29
  • 2
    On 32 bits machines, this method is not recommended as the answer will be i386, i686, etc... I would advice to favor the `getconf LONG_BIT` method. –  Apr 25 '14 at 14:37
  • 3
    @Speredenn the above doesn't check for the 32-bit name, e.g. i386, i686, etc, but for the 64-bit name. Your contention is moot unless there are also synonyms for x86_64 that it could return (e.g. amd64, but can it?) – Nick T Jul 25 '14 at 17:33
  • FYI that does not always seems to match i.e. I see a system where LONG_BIT reports 32, but uname -m reports aarch64 – eglasius May 09 '23 at 07:53
55

getconf LONG_BIT seems to do the trick as well, which makes it even easier to check this since this returns simply the integer instead of some complicated expression.

if [ `getconf LONG_BIT` = "64" ]
then
    echo "I'm 64-bit"
else
    echo "I'm 32-bit"
fi
Victor Zamanian
  • 3,100
  • 24
  • 31
54

Does

uname -a

give you anything you can use? I don't have a 64-bit machine to test on.


Note from Mike Stone: This works, though specifically

uname -m

Will give "x86_64" for 64 bit, and something else for other 32 bit types (in my 32 bit VM, it's "i686").

Mike Stone
  • 44,224
  • 30
  • 113
  • 140
shoover
  • 3,071
  • 1
  • 29
  • 40
15

Be careful, in a chrooted 32-bit env, the uname is still answering like the 64-bit host system.

getconf LONG_BIT works fine.

file /bin/cp or any well-known executable or library should do the trick if you don't have getconf (but you can store programs you can't use, and maybe there are not at this place).

lolesque
  • 10,693
  • 5
  • 42
  • 42
10

You can use , the follow script (i extract this from officially script of "ioquake3") : for example

archs=`uname -m`
case "$archs" in
    i?86) archs=i386 ;;
    x86_64) archs="x86_64 i386" ;;
    ppc64) archs="ppc64 ppc" ;;
esac

for arch in $archs; do
    test -x ./ioquake3.$arch || continue
    exec ./ioquake3.$arch "$@"
done

==================================================================================

I'm making a script to detect the "Architecture", this is my simple code (I am using it with wine , for my Windows Games , under Linux , by each game , i use diferrent version of WineHQ, downloaded from "PlayOnLinux" site.

# First Obtain "kernel" name
KERNEL=$(uname -s)

if      [ $KERNEL = "Darwin" ]; then
        KERNEL=mac
elif        [ $Nucleo = "Linux" ]; then
        KERNEL=linux
elif        [ $Nucleo = "FreeBSD" ]; then
        KERNEL=linux
else
        echo "Unsupported OS"
fi

# Second get the right Arquitecture
ARCH=$(uname -m)

if         [ $ARCH = "i386" ]; then
            PATH="$PWD/wine/$KERNEL/x86/bin:$PATH"
            export WINESERVER="$PWD/wine/$KERNEL/x86/bin/wineserver"
            export WINELOADER="$PWD/wine/$KERNEL/x86/bin/wine"
            export WINEPREFIX="$PWD/wine/data"
            export WINEDEBUG=-all:$WINEDEBUG
            ARCH="32 Bits"
    elif    [ $ARCH = "i486" ]; then
            PATH="$PWD/wine/$KERNEL/x86/bin:$PATH"
            export WINESERVER="$PWD/wine/$KERNEL/x86/bin/wineserver"
            export WINELOADER="$PWD/wine/$KERNEL/x86/bin/wine"
            export WINEPREFIX="$PWD/wine/data"
            export WINEDEBUG=-all:$WINEDEBUG
            ARCH="32 Bits"
    elif    [ $ARCH = "i586" ]; then
            PATH="$PWD/wine/$KERNEL/x86/bin:$PATH"
            export WINESERVER="$PWD/wine/$KERNEL/x86/bin/wineserver"
            export WINELOADER="$PWD/wine/$Nucleo/x86/bin/wine"
            export WINEPREFIX="$PWD/wine/data"
            export WINEDEBUG=-all:$WINEDEBUG
            ARCH="32 Bits"
    elif    [ $ARCH = "i686" ]; then
            PATH="$PWD/wine/$KERNEL/x86/bin:$PATH"
            export WINESERVER="$PWD/wine/$KERNEL/x86/bin/wineserver"
            export WINELOADER="$PWD/wine/$KERNEL/x86/bin/wine"
            export WINEPREFIX="$PWD/wine/data"
            export WINEDEBUG=-all:$WINEDEBUG
            ARCH="32 Bits"
         elif [ $ARCH = "x86_64" ]; then
            export WINESERVER="$PWD/wine/$KERNEL/x86_64/bin/wineserver"
            export WINELOADER="$PWD/wine/$KERNEL/x86_64/bin/wine"
            export WINEPREFIX="$PWD/wine/data"
            export WINEDEBUG=-all:$WINEDEBUG
            ARCH="64 Bits"
    else
        echo "Unsoportted Architecture"
fi

==================================================================================

Now i use this in my bash scripts , because works better in any distro .

# Get the Kernel Name
Kernel=$(uname -s)
case "$Kernel" in
    Linux)  Kernel="linux"              ;;
    Darwin) Kernel="mac"                ;;
    FreeBSD)    Kernel="freebsd"            ;;
* ) echo "Your Operating System -> ITS NOT SUPPORTED"   ;;
esac

echo
echo "Operating System Kernel : $Kernel"
echo
# Get the machine Architecture
Architecture=$(uname -m)
case "$Architecture" in
    x86)    Architecture="x86"                  ;;
    ia64)   Architecture="ia64"                 ;;
    i?86)   Architecture="x86"                  ;;
    amd64)  Architecture="amd64"                    ;;
    x86_64) Architecture="x86_64"                   ;;
    sparc64)    Architecture="sparc64"                  ;;
* ) echo    "Your Architecture '$Architecture' -> ITS NOT SUPPORTED."   ;;
esac

echo
echo "Operating System Architecture : $Architecture"
echo
inukaze
  • 441
  • 1
  • 6
  • 17
  • 4
    You should really learn to use Bash's `case` statement, or basic regex/globbing wildcards, to collapse all four 32-bit handling blocks into a single one, since they are identical. *(Hint: `i[3456]86` is your friend)* – MestreLion Mar 25 '13 at 12:23
  • @MestreLion : Thank you , now i use the method , i describe in the final , because , in some posix system , with "if" , are not working fine . and with use of "case / esac" works when i wish :D . – inukaze Oct 01 '14 at 04:37
7
slot8(msd):/opt # uname -a
Linux slot8a 2.6.21_mvlcge500-electra #1 SMP PREEMPT Wed Jun 18 16:29:33 \
EDT 2008 ppc64 GNU/Linux


Remember, there are other CPU architectures than Intel/AMD...

Kevin Little
  • 12,436
  • 5
  • 39
  • 47
4

You could do something like this:

if $(uname -a | grep 'x86_64'); then
  echo "I'm 64-bit"
else
  echo "I'm 32-bit"
fi
hoyhoy
  • 6,281
  • 7
  • 38
  • 36
-3

Yes, uname -a should do the trick. see: http://www.stata.com/support/faqs/win/64bit.html.