Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts

No equivalent to strace on OS X and the mysterious left square bracket

Posted by plattapuss on October 12th, 2007

Tonight a friend pointed out that there is a weird file in /bin on OS X. If you do 'ls -la /bin' you will most probably see a file called [. That is not a typo, the file has the left square bracket as a name.

Curious off the bat about what it does, I fired up strace and ran the [ file. Except strace doesn't exist on OS X. strace lets you trace system calls and signals on a running file or a file that you run. Basically strace lets you watch what a file is doing. This can be very useful to solve mysterious problems.

So if you are on OS X and you need strace, you can always use ktrace instead. It works mostly the same it seems.

As for the /bin/[ file, it didn't seem to do anything when I ran 'ktrace /bin/['

If I use otool to see what [ depends on it gives me:

PHP:
  1. [root scripts] otool -L /bin/[
  2. /bin/[:
  3.         /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
  4.         /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.3.5)

running strings - /bin/[ gives me long list:

PHP:
  1. [root scripts] strings - /bin/[
  2. __PAGEZERO
  3. __TEXT
  4. __text
  5. __TEXT
  6. __cstring
  7. __TEXT
  8. __textcoal_nt
  9. __TEXT
  10. __DATA
  11. __data
  12. __DATA
  13. __dyld
  14. __DATA
  15. __const
  16. __DATA
  17. __common
  18. __DATA
  19. __IMPORT
  20. __pointers
  21. __IMPORT
  22. __jump_table
  23. __IMPORT
  24. __LINKEDIT
  25. /usr/lib/dyld
  26. /usr/lib/libgcc_s.1.dylib
  27. /usr/lib/libSystem.B.dylib
  28. ,[^_]
  29. [^_]
  30. [^_]
  31. ,[^_]
  32. ,[^_]
  33. ?8!u
  34. ?8!uu?x
  35. |[^_]
  36. __dyld_make_delayed_module_initializer_calls
  37. __dyld_mod_term_funcs
  38. %s: %s
  39. %s: out of range
  40. %s: bad number
  41. argument expected
  42. closing paren expected
  43. missing ]
  44. unknown operand
  45. _NXArgc
  46. _NXArgv
  47. ___progname
  48. __mh_execute_header
  49. _catch_exception_raise
  50. _catch_exception_raise_state
  51. _catch_exception_raise_state_identity
  52. _clock_alarm_reply
  53. _do_mach_notify_dead_name
  54. _do_mach_notify_no_senders
  55. _do_mach_notify_port_deleted
  56. _do_mach_notify_send_once
  57. _do_seqnos_mach_notify_dead_name
  58. _do_seqnos_mach_notify_no_senders
  59. _do_seqnos_mach_notify_port_deleted
  60. _do_seqnos_mach_notify_send_once
  61. _environ
  62. _receive_samples
  63. __DefaultRuneLocale
  64. ___error
  65. ___keymgr_dwarf2_register_sections
  66. ___maskrune
  67. __cthread_init_routine
  68. _abort
  69. _access
  70. _atexit
  71. _errno
  72. _errx
  73. _exit
  74. _getegid
  75. _geteuid
  76. _isatty
  77. _lstat
  78. _mach_init_routine
  79. _stat
  80. _strcmp
  81. _strtol
  82. 8__PAGEZERO
  83. __TEXT
  84. __text
  85. __TEXT
  86. __symbol_stub
  87. __TEXT
  88. __picsymbol_stub__TEXT
  89. $__symbol_stub1
  90. __TEXT
  91. __cstring
  92. __TEXT
  93. __picsymbolstub1__TEXT
  94. __DATA
  95. __data
  96. __DATA
  97. __nl_symbol_ptr
  98. __DATA
  99. __la_symbol_ptr
  100. __DATA
  101. __dyld
  102. __DATA
  103. __const
  104. __DATA
  105. __common
  106. __DATA
  107. 8__LINKEDIT
  108.  
  109. /usr/lib/dyld
  110. /usr/lib/libgcc_s.1.dylib
  111. /usr/lib/libSystem.B.dylib
  112. #x|y
  113. }"Kx@
  114. 9),?H
  115. }"Kx
  116. <8c,
  117. @8c,
  118. 88c,
  119. H8c,
  120. L8c,
  121. P8c-
  122. -<N?
  123. 9k-4
  124. D8c-HH
  125. x?B0
  126. k0d}i
  127. 3x8`
  128. X|BJ
  129. __dyld_make_delayed_module_initializer_calls
  130. __dyld_image_count
  131. __dyld_get_image_name
  132. __dyld_get_image_header
  133. __dyld_NSLookupSymbolInImage
  134. __dyld_NSAddressOfSymbol
  135. libobjc
  136. __objcInit
  137. __dyld_mod_term_funcs
  138. %s: %s
  139. %s: out of range
  140. %s: bad number
  141. argument expected
  142. closing paren expected
  143. missing ]
  144. unknown operand
  145. _NXArgc
  146. _NXArgv
  147. ___progname
  148. __mh_execute_header
  149. _catch_exception_raise
  150. _catch_exception_raise_state
  151. _catch_exception_raise_state_identity
  152. _clock_alarm_reply
  153. _do_mach_notify_dead_name
  154. _do_mach_notify_no_senders
  155. _do_mach_notify_port_deleted
  156. _do_mach_notify_send_once
  157. _do_seqnos_mach_notify_dead_name
  158. _do_seqnos_mach_notify_no_senders
  159. _do_seqnos_mach_notify_port_deleted
  160. _do_seqnos_mach_notify_send_once
  161. _environ
  162. _receive_samples
  163. __DefaultRuneLocale
  164. ___error
  165. ___keymgr_dwarf2_register_sections
  166. ___maskrune
  167. __cthread_init_routine
  168. _abort
  169. _access
  170. _atexit
  171. _errno
  172. _errx$LDBL128
  173. _exit
  174. _getegid
  175. _geteuid
  176. _isatty
  177. _lstat
  178. _mach_init_routine
  179. _stat
  180. _strcmp
  181. _strtol

So, I have no more time to investigate further right now, and Google shows nothing useful. If anyone has an idea of what the mysterious [ binary does, please let me know. Thanks!



Reader Comments

If you’re know basic Bourne-shell script (/bin/sh), you’ll be familiar with the “if” command, the basic syntax of which is:

if ; then

fi

While can be anything, it’s typically a boolean test of some sort. While you could write it like this:

if test $a = 1; then
echo foo
fi

We typically write it like this instead:

if [ $a = 1 ]; then
echo foo
fi

The ‘[‘ is simply an alias for ‘test’ used to make shell scripts more readable. These days, most shells have ‘test’ (and ‘[‘) as built-ins, but in the “old days” this was an external command.

Thank you Lars. It never dawned on me that the [ was actual a file. I *assumed* that it was just a built function of bash.

Upon further looking I go the following command from `man test’.

info coreutils test

Which when entered in the shell will bring up more information on test and [ (The not so mysterious left bracket)

In some Unix systems /bin/[ is a hard link to /bin/test. On OS X Leopard these two files are separate files but they have identical sizes. Diffing the files shows that they are identical binaries.

Thank you Michael for the tip on OS X.