9 ms·
Show HN: Command Line Challenge
- zoidb 10y agoThis was a small side project I completed recently, would love to hear feedback. Thanks!
- garettmd 10y agoI was on the 3rd challenge, listing files in a directory, one per line, and it didn't accept "ls -l", but it did accept "ls"
- zoidb 10y agoYeah it's particular about the output that it expects.
- garettmd 10y agoI guess my point is that "ls" shouldn't be an answer. Typically it will print out multiple files on a line. If it's just checking for output and not the actual command someone entered, there should probably be more than one file in the directory to show that it will actually print one file per line.
- zoidb 10y agoBecause it is executed outside of a terminal (the execution isn't in javascript) you get a single column output. Probably would be better to be more specific in the descriptions, thanks for the suggestion.
- zokier 10y agoThe mostly correct answer is `ls -1`. Just mostly, because it falls to the classic unix trap (filenames can contain almost anything) which also shows that the challenge is ill defined. What is the expected result if the filename contains newlines? And this is not just some hypothetical scenario, just today at work I encountered a file with cursor movement terminal escape sequences in the filename.
- lisivka 10y ago`ls -1b` should work correctly in your case. Option -b (or --escape) enables C-style escapes. IMHO, it should be on by default.
- saghm 10y agoAlthough it often doesn't get printed like that, shells do consider the output of `ls` to be multiple lines. Try doing `ls > foo.txt` and looking at the output file (or more directly, `ls | wc -l`).
- jjnoakes 10y agoThat isn't the shell considering the output one per line. ls will change the way it writes its output if it detects that stdout is a tty versus a pipe or redirect.
- JoshTriplett 10y agoIt seems to accept any command that produces the expected output, though. That question should specifically say that it only wants the filenames, which would make it clear that `ls -l` doesn't produce the desired result.
- brennen 10y agoSame. Seems like the wording on some questions could use tweaking. Not bad overall, though.
- notheguyouthink 10y agoIf anything, i'd argue that it's incorrect. I first tried `ls -l`, then realized "oh, there could be hidden files so `-l` is not correct. Yet, `ls -la` failed too. To list "all files", you'd need to include hidden right? Well, to be sure, at least.
- tedmiston 10y agoI took this to mean it wanted only filenames and nothing else. I used: ls -1
- JoshTriplett 10y agoI 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 10y ago> 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 10y agoTeaching efficient bash usage and teaching portable shell scripting seem related but distinct. This challenge specifically mentions that it uses bash.
- zokier 10y agoYes sure, I wasn't trying to say that going full bash is a bad thing. I was merely presenting an alternative.
- zoidb 10y agoAh good point, the commands are run in a bash 4 subshell actually but by default the globstar option is off.
- JoshTriplett 10y agoHave you considered running the commands directly in JavaScript, rather than via AWS? With some work, you could run everything inside emscripten in the browser, and then you don't need to worry about security, sandboxing, or scaling.
- zoidb 10y agoYeah though this was pretty easy to setup and I was looking to replicate an authentic command line experience including the standard unix utilities.
- akavel 10y agoIn this case you'd probably be better "just" going for http://stackoverflow.com/questions/6030407/how-does-linux-emulator-in-javascript-by-fabrice-bellard-work http://stackoverflow.com/questions/6030407/how-does-linux-em... ?
- coherentpony 10y agogrep -rl 500 . wasn't accepted. Am I wrong or is it wrong?
- leblancfg 10y agoYou are: grep matches strings, not integers. grep -rl '500' works just fine.
- tne 10y agoThere is no concept of an integer on an argument vector. Quoting in bash just escapes IFS characters (usually whitespace) to control whether to include them in a given argument on the vector, but these arguments (as passed to exec) are always character strings (with or without quoting).
- godelski 10y agoInterestingly enough grep -rl "500" . doesn't work because it returns with the "./".
- snuxoll 10y agoOnly filenames matching access.log should be returned. Unfortunately, since shopt globstar is disabled I ended up needing to do this: grep 500 $(find . -type f -iname "access.log*")
- JoshTriplett 10y agoYou could also include "shopt -s globstar; " at the beginning of your line.
- joshka 10y agogrep -r 500 --include access.log
- slavik81 10y agoThat returns the filenames in the format "./access.log" but it wanted "access.log". It's a bug. I used echo -e 'access.log\naccess.log.1\nREADME'. :D
- meggar 10y agoI tried "rm -rf". Not sure if it worked.
- ianmcgowan 10y agoI got stuck on this one too. Strangely "find . -delete" worked fine. I'm getting Internal Server Error" now, so perhaps a victim of it's own popularity?
- wichert 10y agoIt looks a bit like the cwd is shared between multiple users accessing the site? I suddenly got errors that access.log disappears, after which my pwd seemed to randomly change.
- zoidb 10y agoNothing is shared in fact every time you submit a command you get a new subshell in a new container. If it is reproducible I will track down the problem.
- akavel 10y agoThe finale was weird for me, kinda anticlimactic (back to "hello world"); is that how it's expected to behave? No "finished" message or something? Or is my NoScript interfering somehow? She is betraying us! Russia alone must save Europe. Our gracious sovereign recognizes his high vocation and will be true to it. That is the one thing I have faith in! Our good and wonderful sovereign has to perform the noblest role on earth, and he is so virtuous and noble that God will not forsake him. He will fulfill his vocation and crush the hydra of revolution, which has become more terrible than ever in the person of this murderer and villain! # Correct! # You have a new challenge! # 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" hello world # Correct! bash(0)>
- mnemotronic 10y ago# 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)> echo '"hello world".' "hello world". bash(0)> What is this, Android? Sheesh.
- schoen 10y agoNach dem Spiel ist vor dem Spiel? https://en.wikipedia.org/wiki/Sepp_Herberger#References_in_popular_culture https://en.wikipedia.org/wiki/Sepp_Herberger#References_in_p... (I would also like it if the site somehow indicated that you got to the end or congratulated you on finishing everything.)
- zoidb 10y agoI honestly didn't think anyone would complete all of them :) I'll put something cool at the end, thanks for the suggestion.
- inetknght 10y agoAfter completing the challenges (only had to lookup references on bash parameter expansion and how to read lines without parsing them), I would say that it might be helpful to have some reference information available whether via clicking to a third party URL. It'd also be _really_ nifty to be able to compare my solutions against others' solutions.
- ianmcgowan 10y agoSuper-cool! Some pieces of feedback: 1) It would be nice to have something special happen when you solve all the puzzles, rather than going back to the first. Some javascript balloons dropping from the ceiling? ;_) 2) Some of the problems, it's hard to tell why an answer doesn't work. A side-by-side diff showing my results compared to the expected results might help? 3) After solving (perhaps just one, or maybe all), I'd love to see other people's solutions. That'd be quite educational.
- wlib 10y agoI'm making something related as a side project too, and the major problem I have right now is showing a terminal on the page. As you can see I'm relying on archaic methods... https://term.surge.sh https://term.surge.sh
- johnloeber 10y agoFun! Needs tab-complete.
- cglouch 10y agoI really enjoyed this, it was a nice way to practice/learn some command line tricks. In particular I got better acquainted with the find command. Nice work! My only suggestion would be to have an option to show a solution (yours or perhaps even a user-submitted one) if you get stuck on a particular challenge.
- the_watcher 10y agoI like this a lot, thanks for putting together. Definitely made me think hard about how much of the command line I actually know.
- cleech 10y agofun, although I did cheat a bit on the corrupted text and pulled the expected output from README instead of the input file :)
- zoidb 10y agoThe answers I came up with are in https://github.com/jarv/cmdchallenge/blob/master/challenges.yaml https://github.com/jarv/cmdchallenge/blob/master/challenges.... if you are curious.
- JoshTriplett 10y agoThe description for remove_duplicate_lines needs some clarification, because as written it sounds like either "uniq" or "uniq -u". You should explicitly say that you want the first instance of every duplicated line printed, and all other duplicates not printed, even if not adjacent.
- zoidb 10y agoThanks, also feel free to send a pull requests as I would definitely appreciate contributions.
- adimitrov 10y agoThe 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 10y agoMine 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
- joelthelion 10y agobash(0)> grep GET !$ + grep GET '!$' grep: !$: No such file or directory Mmm. Fake bash.
- zoidb 10y agoEvery command is in a new subshell
- contras1970 10y agoThat 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 10y agohistory 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.
- mauvehaus 10y agofind . -type f -exec grep -q 500 {} \; -print Prints the same list of files as grep -l 500 * , but in a different order; doesn't pass the challenge. Also, grep -Il 500 * doesn't include README, for some reason. file README doesn't work :-(
- _kst_ 10y agobash(0)> pwd Internal Server Error
- zoidb 10y agoIt 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.
- rando832 10y agoInterestingly, 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 10y agoI, too, ended up copying the file to my machine. I also ended up with this: https://gist.github.com/daveloyall/63485c5a08882432b138c0917d264e3b https://gist.github.com/daveloyall/63485c5a08882432b138c0917...
- schoen 10y agoI didn't think we were allowed to even potentially change the order, so I used awk '{if (!c[$0]) { print }; c[$0] = 1 }'
- rando832 10y agoOh ya, I shouldn't have said answer, because uniq is not a way to the answer, just something I naturally reached for while trying to figure out an answer.
- _druu 10y agoawk '!a[$0]++' faces.txt is a touch shorter ^^
- schoen 10y agoThat's the same approach used by the challenge's original creator (in the GitHub link above). It's a clever solution!
- deleted 10y ago[deleted]
- ianmcgowan 10y agoThis 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.
- teddyh 10y agopython: command not found :(
- awqrre 10y agotry perl
- glandium 10y agoIt 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 10y agoIt 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 10y agoLove 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!
- ivan_ah 10y agoIt 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
- Neeek 10y agogrep -R --include="access.log*" "500" Should this not work for challenge 9?
- Neeek 10y agoNevermind, I had it wrong. The line should have read "grep 500 -rh --include='access.log*'"
- godelski 10y agoThe 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.
- userbinator 10y agoJudging by the domain name I was expecting cmd.exe . Personally, I think that would be a bit more of a challenge than bash.
- notheguyouthink 10y agoThis 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
- arantius 10y agochallenge "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)