다음 정보가 포함된 텍스트 파일이 있습니다.
Game Copies_Sold(M) Release_date Genre
God_of_War 19 20/04/2018 Action-Adventure
Uncharted_4 16 10/05/2016 Action-adventure
Spider-Man 13 07/09/2018 Action-adventure
The_Witcher_3 10 18/05/2015 Action_role-playing
두 번째 열의 숫자를 합산해야 하므로 다음 스크립트를 작성했습니다.
#!/bin/bash
file=$1
s=0
tail -n +2 $file |cut -f 2 |
{ while read line
do
s=$(( $s+$line ))
done <$file }
echo $s
하지만 분명히 내가 뭔가 잘못하고 있습니다. 여기서 무엇을 해야 할까요? 감사합니다!
답변1
다음과 같아야 합니다.
#! /bin/sh -
file=${1?}
awk 'NR >= 2 {sum += $2}; END {print sum+0}' < "$file"
접근 방식에 문제가 있습니다.
- 최소한 하나의 인수가 스크립트에 전달되었는지 확인하지 않습니다(대략 여기에서 설명
${1?}
). - 주변에 따옴표가 없습니다.
$file
--
옵션의 끝을 표시하기 위해 누락됨tail
(니트피키: 다음과 동일)-
쉐르본에 위치)- 기본 구분 기호
cut
는 TAB이고 입력은 공백으로 구분된 것처럼 보입니다. 기본awk
구분 기호는 공백(공백 및 탭 포함) 수입니다. - 루프에 파이프를 연결하고 해당 루프의 입력을 리디렉션하기도 합니다
$file
. - 이전에 누락되거나
;
개행됨}
- 누락된
-r
옵션read
- Bash에서는 파이프의 가장 오른쪽 구성 요소도 하위 쉘에서 실행되므로(
lastpipe
이 옵션이 활성화되지 않은 경우)$s
파이프가 반환된 후에 변수에 대한 변경 사항이 손실됩니다. - 하지만 먼저쉘 루프를 사용하여 텍스트를 처리하고 있습니다. 이는 일반적으로 나쁜 습관이고 비효율적이며 올바르게 수행하기 어렵습니다..
- 여기 상황도 당신만큼 나쁩니다.외부 입력에 셸 연산을 사용하면 Bash에 명령 주입 취약점이 발생합니다..
- 스크립트에는 bash와 관련된 내용이 없으므로 시스템의
sh
.
이러한 오류 중 일부는 다음과 같습니다.주택 검사(시스템에 독립 실행형 소프트웨어로 설치할 수도 있습니다).
여기에는 다음이 제공됩니다.
$ shellcheck myscript
Line 4:
tail -n +2 $file |cut -f 2 |
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
tail -n +2 "$file" |cut -f 2 |
Line 5:
{ while read line
^-- SC2162 (info): read without -r will mangle backslashes.
Line 7:
s=$(( $s+$line ))
^-- SC2030 (info): Modification of s is local (to subshell caused by pipeline).
^-- SC2004 (style): $/${} is unnecessary on arithmetic variables.
^-- SC2004 (style): $/${} is unnecessary on arithmetic variables.
Line 8:
done <$file }
^-- SC2086 (info): Double quote to prevent globbing and word splitting.
Did you mean: (apply this, apply all SC2086)
done <"$file" }
Line 9:
echo $s
^-- SC2031 (info): s was modified in a subshell. That change might be lost.