
Show HN: Command Line Challenge - zoidb
https://cmdchallenge.com
======
ivan_ah
It would be nice to have to have some sort of hints for beginners. Hint 1:
tells you command, Hint 2: tells which options/flags you might need, Hint 3:
shows (a) solution

------
zoidb
This was a small side project I completed recently, would love to hear
feedback. Thanks!

~~~
JoshTriplett
I really like this; reminiscent of the Python Challenge, but for shell.

You should support bash's double-star wildcard, which works recursively.
Several of the challenges that currently require

    
    
        find -name 'access.log*' -print0 | xargs -0 somecommand
    

could just use

    
    
        somecommand **/access.log*
    

instead.

You might also encourage people to look up manpages. For instance, someone who
doesn't know about "grep -h" may want to look at the manpage for grep. You
could make "man grep" link to [http://man7.org/linux/man-
pages/man1/grep.1.html](http://man7.org/linux/man-pages/man1/grep.1.html) .

Tab completion doesn't always include all files; for instance, it doesn't
include split-me.txt

Have you considered logging all unique successful solutions (filtering out
minor whitespace differences) to each challenge? That would let people who
have completed each challenge see other potential approaches to the problem,
and perhaps learn about new commands.

~~~
zokier
> You should support bash's double-star wildcard, which works recursively

It depends on what the educational goals are, but alternatively OP could swing
on the opposite direction and go with a very vanilla POSIX sh style shell
(maybe dash) to discourage bashisms.

I might of course be bit biased because `find` is one of my favorite utils
(generally with -exec instead of -print0|xargs -0) and I practically never use
newfangled doublestar globbing

~~~
JoshTriplett
Teaching efficient bash usage and teaching portable shell scripting seem
related but distinct. This challenge specifically mentions that it uses bash.

~~~
zokier
Yes sure, I wasn't trying to say that going full bash is a bad thing. I was
merely presenting an alternative.

------
ianmcgowan
This is a really fun idea, and I enjoyed going thru it. I like the fact that
it doesn't matter how you get the answer, as long as it's right (seq 100 | tr
'\n' ' ').

This would be a really useful product as part of the interview process for
technical people. I'd ask candidates to self-identify their expertise level,
let them skip questions, and consult google as much as they wanted. You could
have different subjects and maybe mix and match - shell, powershell, python,
postgres etc.

------
godelski
The problem I'm having with this is that the solutions I would use to solve
these aren't acceptable answers. But it is interesting to find other examples
that do work. These shells are extremely restrictive.

------
_kst_

        bash(0)> pwd
        Internal Server Error

~~~
zoidb
It could be an intermittent problem as this is getting a lot of traffic right
now. If it is reproducible please link the challenge or submit a github issue.

------
the_watcher
I like this a lot, thanks for putting together. Definitely made me think hard
about how much of the command line I actually know.

------
joelthelion

      bash(0)> grep GET !$
      + grep GET '!$'
      grep: !$: No such file or directory
    

Mmm. Fake bash.

~~~
zoidb
Every command is in a new subshell

~~~
contras1970
That may be true but the message from grep shows that $! wasn't expanded by
the execution evironment.

BTW i get

    
    
      # Print "hello world".
      # Hint: There are many ways to print text on
      # the command line, one way is with the 'echo'
      # command.
      # 
      # Try it below and good luck!
      # 
      bash(0)> printf "hello world"
      Internal Server Error
      bash(️)>

~~~
groner
history expansion is normally only enabled for interactive shells. They could
turn it on, but if there isn't any history because this isn't really
interactive, it wouldn't do anything useful.

------
rando832
Interestingly, locale can change one answer.

with LC_COLLATE=en_US.UTF-8,

sort faces.txt | uniq -c

5 (◕‿◕)

uniq treats (︺︹︺) as equal to (◕‿◕).

Copied the file to my machine to test.

~~~
sebbsnoprocrast
I, too, ended up copying the file to my machine.

I also ended up with this:
[https://gist.github.com/daveloyall/63485c5a08882432b138c0917...](https://gist.github.com/daveloyall/63485c5a08882432b138c0917d264e3b)

~~~
schoen
I didn't think we were allowed to even potentially change the order, so I used

    
    
      awk '{if (!c[$0]) { print }; c[$0] = 1 }'

~~~
_druu

        awk '!a[$0]++' faces.txt
    

is a touch shorter ^^

~~~
schoen
That's the same approach used by the challenge's original creator (in the
GitHub link above). It's a clever solution!

------
notheguyouthink
This is really cool, good work! As others have mentioned, hints/etc would
definitely be helpful for beginners. I want to post this in our work chat for
the less Unix oriented folks, but they'd just be lost

------
glandium
It doesn't handle glob expansion.

    
    
      bash(0)> awk '{print $1}' access.log*
      + awk '{print $1}' 'access.log*'
      awk: cannot open access.log* (No such file or directory)

~~~
schoen
It does appear to handle glob expansion. Some of the levels have files within
subdirectories, which isn't always completely clear from the challenge text.
In the level you're trying, access.log might not be in the current directory.

------
aashishkoirala
Love it! My bash is quite rusty it seems, couldn't get past the 6th or 7th
one. Will brush up and do the challenge again. Nice work!

------
cleech
fun, although I did cheat a bit on the corrupted text and pulled the expected
output from README instead of the input file :)

~~~
zoidb
The answers I came up with are in
[https://github.com/jarv/cmdchallenge/blob/master/challenges....](https://github.com/jarv/cmdchallenge/blob/master/challenges.yaml)
if you are curious.

~~~
adimitrov
The awk line for duplicate lines without changing ordering is… wow. Awk is
such an underused tool (at least for me.) My solution was:

    
    
        awk '{printf "%2d %s\n", NR, $0}' < faces.txt | sort -k 2 -u | sort -n | sed 's/^...//'
    

Ironically, it also involved awk! But I used it to prepend line numbers, which
uniq and sort can ignore, then re-sort it according to line numbers. Very much
not an ideal solution!

~~~
ianmcgowan
Mine was more procedural - store each line in a hash as you visit it, and only
print lines you haven't already visited. awk is awesome ;-)

awk '!h[$0] {h[$0]=1; print}' faces.txt

~~~
schoen
I also used this approach but the original creator's version posted on GitHub
is remarkably more concise (due to a clever use of the ++ operator).

~~~
ianmcgowan
awk '!h[$0]++' faces.txt

That is clever! Awk golf hole-in-one ;-)

------
arantius
challenge "just the files" description says "Print all files in the current
directory". You mean "print the names of all files ..."

Lots of the challenges have awkward/ambiguous wording like this.

(If you'd like more detailed feedback, email me -- this username @gmail)

------
teddyh

      python: command not found
    

:(

~~~
awqrre
try perl

------
Neeek
grep -R --include="access.log*" "500"

Should this not work for challenge 9?

~~~
Neeek
Nevermind, I had it wrong. The line should have read

"grep 500 -rh --include='access.log*'"

------
userbinator
Judging by the domain name I was expecting cmd.exe .

Personally, I think that would be a bit more of a challenge than bash.

