@@ -2296,14 +2296,18 @@ readSource t = return t
2296
2296
prop_readPipeline = isOk readPipeline " ! cat /etc/issue | grep -i ubuntu"
2297
2297
prop_readPipeline2 = isWarning readPipeline " !cat /etc/issue | grep -i ubuntu"
2298
2298
prop_readPipeline3 = isOk readPipeline " for f; do :; done|cat"
2299
+ prop_readPipeline4 = isOk readPipeline " ! ! true"
2300
+ prop_readPipeline5 = isOk readPipeline " true | ! true"
2299
2301
readPipeline = do
2300
2302
unexpecting " keyword/token" readKeyword
2301
- do
2302
- (T_Bang id ) <- g_Bang
2303
- pipe <- readPipeSequence
2304
- return $ T_Banged id pipe
2305
- <|>
2306
- readPipeSequence
2303
+ readBanged readPipeSequence
2304
+
2305
+ readBanged parser = do
2306
+ pos <- getPosition
2307
+ (T_Bang id ) <- g_Bang
2308
+ next <- readBanged parser
2309
+ return $ T_Banged id next
2310
+ <|> parser
2307
2311
2308
2312
prop_readAndOr = isOk readAndOr " grep -i lol foo || exit 1"
2309
2313
prop_readAndOr1 = isOk readAndOr " # shellcheck disable=1\n foo"
@@ -2359,7 +2363,7 @@ readTerm = do
2359
2363
2360
2364
readPipeSequence = do
2361
2365
start <- startSpan
2362
- (cmds, pipes) <- sepBy1WithSeparators readCommand
2366
+ (cmds, pipes) <- sepBy1WithSeparators (readBanged readCommand)
2363
2367
(readPipe `thenSkip` (spacing >> readLineBreak))
2364
2368
id <- endSpan start
2365
2369
spacing
@@ -2389,6 +2393,10 @@ readCommand = choice [
2389
2393
]
2390
2394
2391
2395
readCmdName = do
2396
+ -- If the command name is `!` then
2397
+ optional . lookAhead . try $ do
2398
+ char ' !'
2399
+ whitespace
2392
2400
-- Ignore alias suppression
2393
2401
optional . try $ do
2394
2402
char ' \\ '
0 commit comments