5

How can I find out if the vim I'm using is 32 or 64 bit? I'm using Ubuntu so this doesn't apply to me, I think. Also I checked

:version

and got this output:

VIM - Vi IMproved 7.3 (2010 Aug 15, compiled May  4 2012 04:21:49)
Inklusive der Korrekturen: 1-429
Verändert von pkg-vim-maintainers@lists.alioth.debian.org
Übersetzt von buildd@
Riesige Version mit GTK2 GUI. Ein- (+) oder ausschließlich (-) der Eigenschaften:
+arabic +autocmd +balloon_eval +browse ++builtin_terms +byte_offset +cindent +clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info
 +comments +conceal +cryptv +cscope +cursorbind +cursorshape +dialog_con_gui +diff +digraphs +dnd -ebcdic +emacs_tags +eval +ex_extra
+extra_search +farsi +file_in_path +find_in_path +float +folding -footer +fork() +gettext -hangul_input +iconv +insert_expand +jumplist +keymap
+langmap +libcall +linebreak +lispindent +listcmds +localmap +lua +menu +mksession +modify_fname +mouse +mouseshape +mouse_dec +mouse_gpm
-mouse_jsbterm +mouse_netterm -mouse_sysmouse +mouse_xterm +mouse_urxvt +multi_byte +multi_lang -mzscheme +netbeans_intg +path_extra +perl
+persistent_undo +postscript +printer +profile +python -python3 +quickfix +reltime +rightleft +ruby +scrollbind +signs +smartindent -sniff
+startuptime +statusline -sun_workshop +syntax +tag_binary +tag_old_static -tag_any_white +tcl +terminfo +termresponse +textobjects +title
+toolbar +user_commands +vertsplit +virtualedit +visual +visualextra +viminfo +vreplace +wildignore +wildmenu +windows +writebackup +X11
-xfontset +xim +xsmp_interact +xterm_clipboard -xterm_save
          System-vimrc-Datei: "$VIM/vimrc"
        Benutzer-vimrc-Datei: "$HOME/.vimrc"
         Benutzer-exrc-Datei: "$HOME/.exrc"
         System-gvimrc-Datei: "$VIM/gvimrc"
       Benutzer-gvimrc-Datei: "$HOME/.gvimrc"
           System-Menü-Datei: "$VIMRUNTIME/menu.vim"
     Voreinstellung für $VIM: "/usr/share/vim"
Übersetzt: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK  -pthread -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/
include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12     -g -O2 -fstack-protecto
r --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1     -I/usr/include/tcl8.5  -
D_REENTRANT=1  -D_THREAD_SAFE=1  -D_LARGEFILE64_SOURCE=1
Linken: gcc   -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -rdynamic -Wl,-export-dynamic  -Wl,-E  -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-nee
ded -o vim   -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfo
ntconfig -lgobject-2.0 -lglib-2.0   -lSM -lICE -lXpm -lXt -lX11 -lXdmcp -lSM -lICE -lm -ltinfo -lnsl  -lselinux  -lacl -lattr -lgpm -ldl  -L/usr/
lib -llua5.1  -Wl,-E  -fstack-protector -L/usr/local/lib  -L/usr/lib/perl/5.14/CORE -lperl -ldl -lm -lpthread -lcrypt -L/usr/lib/python2.7/config
 -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions  -L/usr/lib -ltcl8.5 -ldl -lpthread -lieee -lm -
lruby1.8 -lpthread -lrt -ldl -lcrypt -lm  -L/usr/lib

but it doesn't look like it tells me what I want to know.

  • 3
    Out of curiosity, why is that information important for you? – romainl Jun 30 '15 at 8:37
  • 1
    Because I'm trying to open a large file (5.1GB) – caligula Jun 30 '15 at 8:42
  • @caligula might be useful: vi.stackexchange.com/questions/149/… – muru Jun 30 '15 at 8:53
  • Yes thanks, I'm actually already using that (including the linked stuff), but I'm still having problems. Perhaps I'll soon be able to ask a question, but for now I'm still trying... – caligula Jun 30 '15 at 9:09
  • 1
    -I/usr/lib/x86_64-linux-gnu/... - those are 64-bit includes. – lcd047 Jun 30 '15 at 10:08
11

Since you're on Ubuntu, use the file command:

$ file -L "$(command -v vim)"
/usr/bin/vim.gnome: ELF 64-bit LSB  shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=acb723f1249782755116f93ed45a30e7115ff423, stripped

As you can see, my vim is 64-bit.

We need to use -L since /usr/bin/vim on Ubuntu is a symlink, managed by the Debian alternatives system, and GNU file by default doesn't follow symlinks (thanks to Random832 for pointing this out!).

Or you can check the package architecture:

$ dpkg-query -f '${Package;10}\t${Architecture}\n' -W vim vim-gnome
       vim  amd64
 vim-gnome  amd64

Both of the above commands check the default vim as Carpetsmoker notes. Within Vim, you can do something like:

if system('file -L "' . exepath(v:progpath) . '"') =~ "64-bit"
    echo "yes"
endif

Or we can use Carpetsmoker's suggestion of the /proc/$PID/exe special link, which should be the most portable across Linux systems:

if system('file -L /proc/' . getpid() . '/exe' ) =~ "64-bit"
    echo "yes"
endif

/proc/$PID/exe is special. You can obtain the original executable for that process from /proc/$PID/exe even if it has been deleted, moved or replaced. In such cases, the output of readlink or resolve() on it may not be what you expect. For example, using a temporary copy of bash for illustration:

$ readlink  -f /proc/$$/exe
/tmp/bash (deleted)
$ file "$(readlink -f /proc/$$/exe)"
/tmp/bash (deleted): ERROR: cannot open `/tmp/bash (deleted)' (No such file or directory)

However, instructing file to follow the symlink, or using file - < /proc/self/exe to read directly from it, which works fine:

$ file -L /proc/$$/exe
/proc/10958/exe: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b73723270773c893cf697d20c8d698f86a51635d, stripped
$ file - < /proc/self/exe
/dev/stdin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=b73723270773c893cf697d20c8d698f86a51635d, stripped

We can't use the /proc/self/exe shortcut in Vim's call to system(), or as an argument to file, since then self will refer to the shell used to execute the command (if we used file - </proc/self/exe), or to file itself (if we used file -L /proc/self/exe). We could use /proc/self/exe if we were to read the file from Vim directly - which is what Carpetsmoker's answer does.

  • How about the $MACHTYPE environment variable? I'm not sure how portable that is, though, but at least tcsh and bash seem to set it. – Martin Tournoij Jun 30 '15 at 7:48
  • @Carpetsmoker hmmm... What if you have 32-bit vim on a 64-bit system? (Say, sudo apt-get install vim:i386 on a 64-bit Ubuntu) – muru Jun 30 '15 at 7:49
  • Yeah, it would only check what the host system's using, not how Vim is compiled... Also a small caveat about your answer: it doesn't necessarily check the Vim binary you're running, but rather the 'default' Vim (which may be a different binary). – Martin Tournoij Jun 30 '15 at 7:54
  • @Carpetsmoker how about the update? – muru Jun 30 '15 at 8:07
  • Sorry for the spam, but you can use this to get the path to the current binary: resolve('/proc/' . getpid() . '/exe') ... Should work on most Unix-y systems which have a /proc – Martin Tournoij Jun 30 '15 at 8:07
5

A "pure" Vim way, just because we can:

:let is_64_bits = match(strpart(readfile(resolve('/proc/' . getpid() . '/exe'), 'b', 1)[0], 4, 1), '\%x02') != -1

So, how does it work? Split up in multiple commands:

  1. Get the path to the Vim binary:

    :let file = resolve('/proc/' . getpid() . '/exe')
    
  2. Read the first "line" of the current binary. Reading a "line" makes little sense for binary files, but AFAIK I can't tell Vim to read a n number of bytes:

    :let contents = readfile(file, 'b', 1)[0]
    
  3. Get the fifth byte:

    :let magic = strpart(contents, 4, 1)
    
  4. Check if this byte matches 0x02, if it does, it's a 64-bit binary. Using == '\%x02' or =~ '\%x02' doesn't seem to work, so we use match().

    :let is_64_bits = match(magic, '\%x02') != -1
    

    I got the "magic" byte value from the magic file that the file command uses:

    0   string      \177ELF     ELF
    !:strength *2
    >4  byte        0       invalid class
    >4  byte        1       32-bit
    >4  byte        2       64-bit
    

Note that just using file as per muru's answer is probably better; I'm not sure if this works on all platforms/architectures (although a casual reading of the magic file suggests it would). I was mostly just curious to see if this could be done from within VimScript without any external tools ;-)

  • If readfile supports reading from symlinks, then read directly from /proc/$PID/exe. I'm not sure how resolve will behave with deleted commands. – muru Jun 30 '15 at 8:39
  • 1
    Once you reference /proc that way it isn't "pure Vim", it's "Linux Vim". :) – lcd047 Jun 30 '15 at 10:09
  • @lcd047 sort of but not really. procfs predates Linux by a decade, many systems have it. Linux did extend it heavily, and "as expected" in the world of Unix different implementations are not compatible (/proc/<pid>/path, /proc/<pid>/file)... Some systems may not have it, but making anything truly Unix-wide compatible without explicitly coding it (#ifdef etc.) is damn near impossible. – Martin Tournoij Jun 30 '15 at 10:21
  • 1
    I knew I was forgetting something! We're within Vim, so we don't need the PID. /proc/self/exe! – muru Jun 30 '15 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.