MCPcopy Index your code
hub / github.com/codeaashu/claude-code / handleRedirection

Function handleRedirection

src/utils/bash/commands.ts:860–1091  ·  view source on GitHub ↗
(
  part: ParseEntry,
  prev: ParseEntry | undefined,
  next: ParseEntry | undefined,
  nextNext: ParseEntry | undefined,
  nextNextNext: ParseEntry | undefined,
  redirections: Array<{ target: string; operator: '>' | '>>' }>,
  kept: ParseEntry[],
)

Source from the content-addressed store, hash-verified

858}
859
860function handleRedirection(
861 part: ParseEntry,
862 prev: ParseEntry | undefined,
863 next: ParseEntry | undefined,
864 nextNext: ParseEntry | undefined,
865 nextNextNext: ParseEntry | undefined,
866 redirections: Array<{ target: string; operator: '>' | '>>' }>,
867 kept: ParseEntry[],
868): { skip: number; dangerous: boolean } {
869 const isFileDescriptor = (p: ParseEntry | undefined): p is string =>
870 typeof p === 'string' && /^\d+$/.test(p.trim())
871
872 // Handle > and >> operators
873 if (isOperator(part, '>') || isOperator(part, '>>')) {
874 const operator = (part as { op: '>' | '>>' }).op
875
876 // File descriptor redirection (2>, 3>, etc.)
877 if (isFileDescriptor(prev)) {
878 // Check for ZSH force clobber syntax (2>! file, 2>>! file)
879 if (next === '!' && isSimpleTarget(nextNext)) {
880 return handleFileDescriptorRedirection(
881 prev.trim(),
882 operator,
883 nextNext, // Skip the "!" and use the actual target
884 redirections,
885 kept,
886 2, // Skip both "!" and the target
887 )
888 }
889 // 2>! with dangerous expansion target
890 if (next === '!' && hasDangerousExpansion(nextNext)) {
891 return { skip: 0, dangerous: true }
892 }
893 // Check for POSIX force overwrite syntax (2>| file, 2>>| file)
894 if (isOperator(next, '|') && isSimpleTarget(nextNext)) {
895 return handleFileDescriptorRedirection(
896 prev.trim(),
897 operator,
898 nextNext, // Skip the "|" and use the actual target
899 redirections,
900 kept,
901 2, // Skip both "|" and the target
902 )
903 }
904 // 2>| with dangerous expansion target
905 if (isOperator(next, '|') && hasDangerousExpansion(nextNext)) {
906 return { skip: 0, dangerous: true }
907 }
908 // 2>!filename (no space) - shell-quote parses as 2 > "!filename".
909 // In Zsh, 2>! is force clobber and the remainder undergoes expansion,
910 // e.g., 2>!=rg expands to 2>! /usr/bin/rg, 2>!~root/.bashrc expands to
911 // 2>! /var/root/.bashrc. We must strip the ! and check for dangerous
912 // expansion in the remainder. Mirrors the non-FD handler below.
913 // Exclude history expansion patterns (!!, !-n, !?, !digit).
914 if (
915 typeof next === 'string' &&
916 next.startsWith('!') &&
917 next.length > 1 &&

Callers 1

Calls 6

isFileDescriptorFunction · 0.85
isSimpleTargetFunction · 0.85
hasDangerousExpansionFunction · 0.85
isOperatorFunction · 0.70
pushMethod · 0.45

Tested by

no test coverage detected