105

For those out of the loop, sl is a humourous command line tool that is meant to trip people up if they mistype ls. When invoked it prints a Steam Locomotive. For example:

                          (  ) (@@) ( )  (@)  ()    @@    O     @     O     @      O
                     (@@@)
                 (    )
              (@@@@)

            (   )
         ====        ________                ___________
     _D _|  |_______/        \__I_I_____===__|_________|
      |(_)---  |   H\________/ |   |        =|___ ___|      _________________
      /     |  |   H  |  |     |   |         ||_| |_||     _|                \_____A
     |      |  |   H  |__--------------------| [___] |   =|                        |
     | ________|___H__/__|_____/[][]~\_______|       |   -|                        |
     |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
   __/ =| o |=-O=====O=====O=====O \ ____Y___________|__|__________________________|_
    |/-=|___|=    ||    ||    ||    |_____/~\___/          |_D__D__D_|  |_D__D__D_|
     \_/      \__/  \__/  \__/  \__/      \_/               \_/   \_/    \_/   \_/

However, in the man page for sl, it states the following bug:

BUGS
        It rarely shows contents of current directory.

So, the question remains, are there some conditions, under which sl actually does show the current directory?

  • 45
    +1 for introducing me to a very useful utility I'd been unaware of for decades. – devnull Apr 15 '14 at 3:13
  • 3
    @slm We've assertained that, so I've put in a bug that addresses this critical issue: #9 – user53306 Apr 15 '14 at 6:27
  • 44
    It says it rarely shows the contents of the directory. So I presume they mean if you have files like | | | H |__--------------------| [___] | =| |, sl shows them. – Mr Lister Apr 15 '14 at 10:46
  • 3
    Pull Request inc: github.com/mtoyoda/sl/pull/11 – asteri Apr 17 '14 at 13:55
  • 7
    I have been a Unix/Linux sysadmin for 14 years and had never heard of this incredible tool. It's amazing how much there is to learn. – Michael Martinez Apr 18 '14 at 18:55

10 Answers 10

185

As far as I know, the only condition under which sl shows the current directory is when you mistype it as ls.

  • 8
    +1 Humorous, but I'm hoping for a more authoritative answer. – user53306 Apr 15 '14 at 1:46
  • 37
    @LegoStormtroopr - perhaps you're waiting for LegoEmperor to weigh in? – mikeserv Apr 15 '14 at 1:51
42
  • Lemma: sl prints a steam locomotive
  • Lemma: Valid file names cannot contain forward slashes (although paths can)
  • Lemma: The steam locomotive contains forward slashes:

    $ touch '                          (  ) (@@) ( )  (@)  ()    @@    O     @     O     @      O
    >                      (@@@)
    >                  (    )
    >               (@@@@)
    > 
    >             (   )
    >          ====        ________                ___________
    >      _D _|  |_______/        \__I_I_____===__|_________|
    >       |(_)---  |   H\________/ |   |        =|___ ___|      _________________
    >       /     |  |   H  |  |     |   |         ||_| |_||     _|                \_____A
    >      |      |  |   H  |__--------------------| [___] |   =|                        |
    >      | ________|___H__/__|_____/[][]~\_______|       |   -|                        |
    >      |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
    >    __/ =| o |=-O=====O=====O=====O \ ____Y___________|__|__________________________|_
    >     |/-=|___|=    ||    ||    ||    |_____/~\___/          |_D__D__D_|  |_D__D__D_|
    >      \_/      \__/  \__/  \__/  \__/      \_/               \_/   \_/    \_/   \_/'
    touch: cannot touch ‘[...]’: No such file or directory
    

Conclusion: sl never shows the current directory. QED.

  • 6
    It contains several /'es, which are not allowed in Unix filenames. – mtak Apr 15 '14 at 15:03
  • 2
    If you did a mkdir -p "$(dirname "$(sl)")" you could do touch "$(sl)". Of course, you might be testing the limits of your OS/FS. And have fun cleaning that up. – Kevin Apr 15 '14 at 18:51
  • 3
    @MrLister Surely that would only be possible if the filesystem also had a bug in it to allow such files to be created. Do you have a reference? – l0b0 Apr 16 '14 at 7:17
  • 1
    @VolkerSiegel: Not really. Windows supports both / and \, and they mean the same thing. – Konrad Borowski Apr 17 '14 at 9:38
  • 3
    If you have a file called H (for instance), then sl does indeed show it. It's just that it also shows a lot of other things. :-) – ShreevatsaR Apr 20 '14 at 12:52
38

Here's a patch to fix that bug :)

diff --git a/sl.c b/sl.c
index 2eeceb3..f2213ad 100644
--- a/sl.c
+++ b/sl.c
@@ -37,6 +37,7 @@
 #include <curses.h>
 #include <signal.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include "sl.h"

 int ACCIDENT  = 0;
@@ -71,6 +72,13 @@ void option(char *str)
 int main(int argc, char *argv[])
 {
     int x, i;
+    
+    srand(time(NULL));
+    if(rand() % 100 < 10)
+    {
+       /* 10% chance of directory listing :) */
+       execv("/bin/ls", argv);
+    }

     for (i = 1; i < argc; ++i) {
    if (*argv[i] == '-') {
  • 5
    Oh lord. You sir are a scholar and a genius. – user53306 Apr 16 '14 at 2:57
  • 3
    Please... please... file a pull request for that patch – user53306 Apr 16 '14 at 3:51
  • 1
    Y'know, I actually have no idea how to do that? I don't use github myself except as a web-based download portal for other people's software. You can do that if you like. I officially disclaim all copyright on the above code and place it in the public domain. – Ionoclast Brigham Apr 16 '14 at 3:57
  • +1, but that's not exactly 10% - rand() "Returns a pseudo-random integral number in the range between 0 and RAND_MAX," which is library-dependent but may not be divisible by 100. – l0b0 Apr 16 '14 at 7:19
  • 1
    Technically, execx() functions can return. From man 3 exec: "If any of the exec() functions returns, an error will have occurred. The return value is -1, and the global variable errno will be set to indicate the error." – Ionoclast Brigham Apr 16 '14 at 16:40
24

You can check the source code here - https://github.com/mtoyoda/sl, alas there is no other options other than the ones documented and sadly nothing that will actually print the names of files.

So it looks like @sfyn's answer is the correct one.

12

Note that I0b0's answer is only a proof that sl will never display all and only the current directory listing. However, there are circumstances in which sl will display the current directory listing together with additional 'information'.

For example, in an empty directory:

$ touch '                          (  ) (@@) ( )  (@)  ()    @@    O     @     O     @      O'
$ touch '                   (@@@)'
$ touch '                  (    )'
$ touch '              (@@@@)'
$ touch '            (   )'
$ sl

will on the first six lines list the contents of the directory, and on the remaining 10 lines will conveniently embellish this listing with an image of a train (without smoke).

  • 3
    Or, the current directory could be an empty set. In which case all the (non-existent) files are displayed along with a picture of a train. :-) – Kevin Seifert Nov 17 '15 at 17:49
6

I know that Lego Stormtroopr has logged a ticket so that the critical issue can be addressed. Who knows much time it might take for a fix to be rolled out?

As such, I've provided a workaround so that the impact due to the grave issue is minimized. You can create a shell function sl that would execute sl:

sl() {
  ((RANDOM%42)) && command sl || ls;
}

Now invoking sl will, sporadically, list the directory contents.

2

If you alias it to ls, it'll print the current directory - in fact, once I stopped laughing at the steam engine locomotive, I added that to my list of aliases.

1

You could always review it's source code for yourself, and you would see under no condition does it ever perform the actual ls command nor display directories.

https://github.com/mtoyoda/sl

The source is rather simple actually. Even if you are "not a coder" you should still be able to understand most of it.

I believe the "bug" you posted above is really just in jest (and to cause discussion like this lol)

1

Yes, sl will act just like ls if you set up the appropriate alias in bash or whatever shell you are using!

I actually have several alias for ls including

alias ls='ls -FG'
alias ll='ls -lFG'

so thanks for the suggestion — I will add

alias sl='ls -FG'

(Not that I ever remember typing sl but then I tend to us ll or lh!)

-1

You could do like I do also...

mv /usr/games/sl /usr/games/sl-OLD

mv /usr/games/LS /usr/games/LS-OLD

nano /usr/games/sl

Paste the following:

#!/bin/bash

echo "YOU TYPED 'sl' INSTEAD OF 'ls'!"

/usr/games/sl-old

echo "Guess I can list it anyways..."

/bin/ls

Press CTRL+X to exit and Y to save.

nano /usr/games/LS

Paste the following:

#!/bin/bash

echo "YOU TYPED 'LS' INSTEAD OF 'ls'!"

/usr/games/sl-old

echo "Guess I can list it anyways..."

/bin/ls

Press CTRL+X to exit and Y to save.

P.S: You're welcome for reviving this.. searching to "sl linux command" still brings this thread up, so I thought I would give a real answer as to how I made it list the files...

Your Answer

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